事務管理
事務是一組原子操作(一組SQL執(zhí)行)的工作單元,這個工作單元中的所有原子操作在進行期間,與其它事務隔離,免于數(shù)據(jù)源的交相更新而發(fā)生混亂,事務中的所有原子操作,要嘛全部執(zhí)行成功,要嘛全部失?。词怪挥幸粋€失敗,所有的原子操作也要全部撤消)。 在JDBC中,可以用Connection來管理事務,可以將Connection的AutoCommit設定為false,在下達一連串的SQL語句后,自行呼叫Connection的commit()來送出變更,如果中間發(fā)生錯誤,則撤消所有的執(zhí)行,例如: try { ..... connection.setAutoCommit(false); ..... // 一連串SQL操作 connection.commit(); } catch(Exception) { // 發(fā)生錯誤,撤消所有變更 connection.rollback(); } Hibernate本身沒有事務管理功能,它依賴于JDBC或JTA的事務管理功能,預設是使用JDBC事務管理,事實上,下面的程序只是對JDBC事務管理作了個簡單的封裝: try { session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); .... tx.commit(); } catch(Exception e) { tx.rollback(); } 在執(zhí)行openSession()時,實際上Hibernate是在開啟一個Connection,而執(zhí)行beginTransaction()時,實際上會執(zhí)行Connection的setAutoCommit(false)方法,最后的tx.commit()就是呼叫Connection的 commit()方法,有興趣的話,可以研究net.sf.hibernate.transaction.JDBCTransaction中的begin ()與commit()方法,可以找到對應的JDBC代碼。 session = sessionFactory.openSession(); <-- Connection connection = ....; tx = session.beginTransactioin(); <-- connection.setAutoCommit(false); tx.commit(); <-- connection.commit(); session.close(); <-- connection.close(); 所以使用JDBC事務管理,最后一定要執(zhí)行Transaction的commit(),如果沒有,則之前對session所下的所有指令并不會有效果。 Hibernate可以透過配置文件來使用基于JTA的事務管理,JTA事務管理可以跨越數(shù)個Session,而不是像JDBC事務管理只能在一個Session中進行,我們在hibernate.cfg.xml中如下撰寫: <hibernate-configuration> <session-factory> .... <property name="hibernate.transaction.factory_class"> net.sf.hibernate.transaction.JTATransactionFactory </property> .... </session-factory> </hibernate-configuration> 或者是在hibernate.properties中撰寫: hibernate.transaction.factory_class=net.sf.hibernate.transaction.JTATransactionFactory JTA的事務是由JTA容器管理,而不是像JDBC事務管理一樣由Connection來管理事務,所以我們不是由Session來開始事務,而是如下進行: javax.transaction.UserTransaction tx = new InitialContext().lookup("javax.transaction.UserTransaction"); Session s1 = sessionFactory.openSession(); .... // 一些save、update等 s1.flush(); s1.close(); ... Session s2 = sf.openSession(); ... s2.flush(); s2.close(); .... tx.commit(); 同樣的,如果您有興趣,可以看net.sf.hibernate.transaction.JTATransaction中的begin()與commit()方法代碼,看看Hibernate如何封裝JTA的事務管理代碼的。 |
|
來自: WindySky > 《Hibernate入門》