Java模拟银行转账(操作事务)
案例:A給B轉10000塊錢
1.準備工作:在數據庫先建一張表(t_account):
id name balance
-------------------------
1 A ?20000
2 B?0
-------------------------
?
2.模擬銀行轉賬:
實現的步驟:
(1).查詢A的賬戶余額
SELECT * FROM ?t_account ?WHERE name='A' AND balance>=10000
>=10000:執行轉賬 ?GOTO(2)
<10000:親,余額不足
(2).從A的賬戶上扣除10000塊
?UPDATE t_account SET balance=balance-10000 WHERE name='A'
(3).中途一切正常,GOTO(4)
???中途異常(如停電),整個事務回滾(rollback)到最初狀態,即返回從A賬戶上扣除的1000給A
(4).在趙敏的賬戶上面加10000塊
?UPDATE t_account SET balance=balance+10000 WHERE name='趙敏'
(5).提交事務(commit)
?
在程序中如何操作事務(操作事務的模板)
try{
//1.DML操作默認是自動提交的,要使用事務,就應該將事務提交方式改變為手動提交
Connection對象.setAutoCommit(false);
//操作1
//操作2
//異常
//操作3
//2.提交事務(使所有上一次提交/回滾后進行的更改成為持久更改(即一旦提交,便不能更改),并釋放此Connection 對象當前持有的所有數據庫鎖。)
Connection對象.commit();
}catch(Exception e){
e.printStackTrace();
//3.回滾事務(取消在當前事務中進行的所有更改,并釋放此Connection 對象當前持有的所有數據庫鎖)
Connection對象.rollback();
}
模擬銀行轉賬代碼:
AccountTest
//模擬銀行轉賬(A轉賬給B) public class AccountTest {@Testpublic void testAccount() throws Exception {Connection conn = null;PreparedStatement ps = null;ResultSet result = null;try{//查詢A賬戶余額有無夠10000String sql = "select * from account where name = ? and balance >= ?";conn = DBUtils.getConnection();//將事務設置為手動提交conn.setAutoCommit(false);ps = conn.prepareStatement(sql);ps.setString(1, "A");ps.setInt(2, 10000);result = ps.executeQuery();if(!result.next()){throw new RuntimeException("您的余額不足");}//扣除A賬戶10000sql = "update account set balance = balance - ? where name = ?";ps = conn.prepareStatement(sql);ps.setInt(1, 10000);ps.setString(2, "A");ps.executeUpdate();//模擬中途斷電異常//System.out.println(1/0);//B賬戶增加10000sql = "update account set balance = balance + ? where name = ?";ps = conn.prepareStatement(sql);ps.setInt(1, 10000);ps.setString(2, "B");ps.executeUpdate();conn.commit();//提交(要整個事務都完成才能提交,因為提交之后就不能改變了)}catch(Exception e){e.printStackTrace();conn.rollback();}DBUtils.close(conn, ps, result);}}DBUtils:數據庫連接
public class DBUtils {private static Properties p = new Properties();static{try {ClassLoader loader = Thread.currentThread().getContextClassLoader();InputStream in = loader.getResourceAsStream("db.properties");p.load(in);Class.forName(p.getProperty("driverClassName"));//加載注冊驅動只需加載一次,因而用靜態代碼塊} catch (Exception e) {e.printStackTrace();}}//獲取連接對象public static Connection getConnection(){try {return DriverManager.getConnection(p.getProperty("url"), p.getProperty("username"), p.getProperty("password"));} catch (Exception e) {e.printStackTrace();}return null;}public static void close(Connection conn,Statement state,ResultSet result){try {if(result != null){result.close();}} catch (SQLException e) {e.printStackTrace();}finally{try {if(conn != null){conn.close();}} catch (SQLException e) {e.printStackTrace();}finally{try {if(state != null){state.close();}} catch (SQLException e) {e.printStackTrace();}}}}}
資源文件
db.properties
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/hcd username=root password=admin總結
以上是生活随笔為你收集整理的Java模拟银行转账(操作事务)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python:浅析python 中__n
- 下一篇: bzoj1051[kosaraju算法]