事務的原子性 :事務是資料庫的邏輯工作單位,事務中包含的各操作要麼都做,要麼都不做 。
要實現事務的原子性,單單靠一條commit或是rollback命令還是不行的,因為例如commit命令它只是將一個事務中執行成功的DML語句提交給資料庫裡。如果要實現事務的原子性,則就需要commit和rollback命令配合上程式上的一個業務邏輯才能可以,具體業務邏輯程式碼如下示例程式碼:
1.現象
2.原因
本表的Storage Engine 為myisam,不是innoDB,不支援事務處理 rollback()
3.解決方法
使用 alter table xxxx engine = innoDB ; 將表改為 InnoDB 引擎,結果回滾正常。
4.程式碼
private void testCrud() {
Connection conn = null; //連線物件
PreparedStatement pstmt = null; //預編譯的SQL語句物件
try{
//載入MySQL驅動程式
Class.forName("com.mysql.jdbc.Driver");
//連線字串
String url = "jdbc:mysql://localhost:3306/test";
//建立資料庫連線
conn = DriverManager.getConnection(url,"root","");
//設定事務的隔離級別
// conn.setTransactionIsolation(Connection. TRANSACTION_REPEATABLE_READ);
//設定自動提交為false,開始事務
conn.setAutoCommit(false);
//帶引數的更新語句
String sql = "INSERT INTO user_info (username ,password ,age )values(?,?,?)";
//準備語句
pstmt = conn.prepareStatement(sql);
//繫結引數,執行更新語句,將張三的賬戶金額減去1000元
pstmt.setString(1, "zhangui");
pstmt.setString(2, "1111");
pstmt.setInt(3, 300);
pstmt.execute();
//繫結引數,執行更新語句,將李四的賬戶金額增加1000元
// pstmt.setString(1, "zzzzzzzzzzzzzzzzz"); //綁定了非法引數
//pstmt.setString(2, "1111111111");
//pstmt.setInt(3, 500);
//pstmt.execute(); //將丟擲SQL異常
//提交事務
//conn.commit();
System.out.println("事務已提交,轉賬成功!");
//關閉語句、連線
pstmt.close(); conn.close();
}catch(Exception e){
conn.rollback(); //回滾事務
System.out.println("事務回滾成功,沒有任何記錄被更新!");
}catch(Exception re){
System.out.println("回滾事務失敗!");
}
e.printStackTrace();
}finally{
if(pstmt!=null) try{pstmt.close();}catch(Exception ignore){}
if(conn!=null) try{conn.close();}catch(Exception ignore){}
事務的原子性 :事務是資料庫的邏輯工作單位,事務中包含的各操作要麼都做,要麼都不做 。
要實現事務的原子性,單單靠一條commit或是rollback命令還是不行的,因為例如commit命令它只是將一個事務中執行成功的DML語句提交給資料庫裡。如果要實現事務的原子性,則就需要commit和rollback命令配合上程式上的一個業務邏輯才能可以,具體業務邏輯程式碼如下示例程式碼:
1.現象
2.原因
本表的Storage Engine 為myisam,不是innoDB,不支援事務處理 rollback()
3.解決方法
使用 alter table xxxx engine = innoDB ; 將表改為 InnoDB 引擎,結果回滾正常。
4.程式碼
private void testCrud() {
Connection conn = null; //連線物件
PreparedStatement pstmt = null; //預編譯的SQL語句物件
try{
//載入MySQL驅動程式
Class.forName("com.mysql.jdbc.Driver");
//連線字串
String url = "jdbc:mysql://localhost:3306/test";
//建立資料庫連線
conn = DriverManager.getConnection(url,"root","");
//設定事務的隔離級別
// conn.setTransactionIsolation(Connection. TRANSACTION_REPEATABLE_READ);
//設定自動提交為false,開始事務
conn.setAutoCommit(false);
//帶引數的更新語句
String sql = "INSERT INTO user_info (username ,password ,age )values(?,?,?)";
//準備語句
pstmt = conn.prepareStatement(sql);
//繫結引數,執行更新語句,將張三的賬戶金額減去1000元
pstmt.setString(1, "zhangui");
pstmt.setString(2, "1111");
pstmt.setInt(3, 300);
pstmt.execute();
//繫結引數,執行更新語句,將李四的賬戶金額增加1000元
// pstmt.setString(1, "zzzzzzzzzzzzzzzzz"); //綁定了非法引數
//pstmt.setString(2, "1111111111");
//pstmt.setInt(3, 500);
//pstmt.execute(); //將丟擲SQL異常
//提交事務
//conn.commit();
System.out.println("事務已提交,轉賬成功!");
//關閉語句、連線
pstmt.close(); conn.close();
}catch(Exception e){
try{
conn.rollback(); //回滾事務
System.out.println("事務回滾成功,沒有任何記錄被更新!");
}catch(Exception re){
System.out.println("回滾事務失敗!");
}
e.printStackTrace();
}finally{
if(pstmt!=null) try{pstmt.close();}catch(Exception ignore){}
if(conn!=null) try{conn.close();}catch(Exception ignore){}
}
}