事務(wù)管理
事務(wù)是一組原子操作(一組SQL執行)的工作單元,這個(gè)工作單元中的所有原子操作在進(jìn)行期間,與其它事務(wù)隔離,免于數據源的交相更新而發(fā)生混亂,事務(wù)中的所有原子操作,要嘛全部執行成功,要嘛全部失?。词怪挥幸粋€(gè)失敗,所有的原子操作也要全部撤消)。
在JDBC中,可以用Connection來(lái)管理事務(wù),可以將Connection的AutoCommit設定為false,在下達一連串的SQL語(yǔ)句后,自行呼叫Connection的commit()來(lái)送出變更,如果中間發(fā)生錯誤,則撤消所有的執行,例如:
try {
.....
connection.setAutoCommit(false);
.....
// 一連串SQL操作
connection.commit();
} catch(Exception) {
// 發(fā)生錯誤,撤消所有變更
connection.rollback();
}
Hibernate本身沒(méi)有事務(wù)管理功能,它依賴(lài)于JDBC或JTA的事務(wù)管理功能,預設是使用JDBC事務(wù)管理,事實(shí)上,下面的程序只是對JDBC事務(wù)管理作了個(gè)簡(jiǎn)單的封裝:
try {
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
....
tx.commit();
} catch(Exception e) {
tx.rollback();
}
在執行openSession()時(shí),實(shí)際上Hibernate是在開(kāi)啟一個(gè)Connection,而執行beginTransaction()時(shí),實(shí)際上會(huì )執行Connection的setAutoCommit(false)方法,最后的tx.commit()就是呼叫Connection的 commit()方法,有興趣的話(huà),可以研究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事務(wù)管理,最后一定要執行Transaction的commit(),如果沒(méi)有,則之前對session所下的所有指令并不會(huì )有效果。
Hibernate可以透過(guò)配置文件來(lái)使用基于JTA的事務(wù)管理,JTA事務(wù)管理可以跨越數個(gè)Session,而不是像JDBC事務(wù)管理只能在一個(gè)Session中進(jìn)行,我們在hibernate.cfg.xml中如下撰寫(xiě):
<hibernate-configuration>
<session-factory>
....
<property name="hibernate.transaction.factory_class">
net.sf.hibernate.transaction.JTATransactionFactory
</property>
....
</session-factory>
</hibernate-configuration>
或者是在hibernate.properties中撰寫(xiě):
hibernate.transaction.factory_class=net.sf.hibernate.transaction.JTATransactionFactory
JTA的事務(wù)是由JTA容器管理,而不是像JDBC事務(wù)管理一樣由Connection來(lái)管理事務(wù),所以我們不是由Session來(lái)開(kāi)始事務(wù),而是如下進(jìn)行:
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的事務(wù)管理代碼的。

