commit和rollback是數據庫事務的兩個概念。
一個數據庫事務有開始和結束邊界(boundary), 位於boundary的對數據庫的各種操作認為是對該事務的操作。
一個事務的要占用數據庫的一些資源,比如可能獲得數據庫的某個表的某條記錄的lock,如果一個事務長期占用資源而不去釋放,那么對其他的事務是不利的,可能會使得速度很慢。
所以對數據庫操作的正確做法是讓事務短小,只做一些應該在事務里邊做的事情,以最快的速度讓一個事務結束,從而釋放該事務所占有的資源。
如何讓一個事務結束?commit或者rollback。兩者選其一,而且必選其一,才能夠確保一個事務被可靠的,安全的終止。commit意味着對事務中的操作確定,rollback意味着對事務中的操作否定。
JDBC中如何正確的處理事務?
1。如果需要保持一些操作的原子性,比如轉帳就需要原子性,那么必須要將這些操作放在一個事務中。
Connection conn = 。。。;
conn.setAutoCommit(false);
//從一個人那里扣錢
//往另一個人那里加錢
//做一些其他的事情,比如通過jms來廣播一條成功的消息
conn.commit();
上面的代碼看起來似乎完成了轉帳的操作,其實需要的改進的地方很多。
1)不能保證上面的事務能夠可靠的終止。
如果對數據庫的扣錢,加錢操作失敗,那么conn.commit()不會被執行。
2)通過jms來廣播消息動作跟這個事務沒有太大的關系,所以不應該放在事務中。試想如果jms廣播需要花5s的時間,那么該事務結束的時間就要推遲5s,釋放lock的時間也要被推遲5s!
正確的代碼:
Connection conn = 。。。;
boolean success = false;
try{
conn.setAutoCommit(false);
//從一個人那里扣錢
//往另一個人那里加錢
conn.commit();
success = true;
}
catch(SQLException e){
conn.rollback();
success = false;
}
if(success)//做一些其他的事情,比如通過jms來廣播一條成功的消息
2。如果不需要處理原子性的操作,比如查詢,那么只需要conn.setAutoCommit(true);做就可以了。