Hibernate Transaction management

Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的 Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装. 默认情况下使用的是JDBCTransaction.
hibernate.transaction.factory_class org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.factory_class org.hibernate.transaction.JDBCTransactionFactory

最好是什么都不配,让Hibernate采用默认的事务处理机制.而且真正的事务处理要放到业务层来做.

1. JDBC Transaction

看看使用JDBC Transaction的时候我们的代码例子:

Session session = sf.openSession();
Transaction tx = session.beginTransactioin();
...
session.flush();
tx.commit();
session.close();


这是默认的情况,当你在代码中使用Hibernate的Transaction的时候实际上就是JDBCTransaction。那么JDBCTransaction究竟是什么东西呢?来看看源代码就清楚了:
public class JDBCTransaction implements Transaction

public void begin() throws HibernateException {

...
if (toggleAutoCommit) jdbcContext.connection().setAutoCommit(false);
...
}

这是启动Transaction的方法,再来看提交方法:
public void commit() throws HibernateException {
...
jdbcContext.connection().commit();
...
jdbcContext.connection().setAutoCommit( true );
...
}

我现在把用 Hibernate写的例子翻译成JDBC,大家就一目了然了:

Connection conn = ...; <--- session = sf.openSession();

conn.setAutoCommit(false); <--- tx = session.beginTransactioin();

... <--- ...

conn.commit(); <--- tx.commit(); (对应左边的两句)
conn.setAutoCommit(true);

conn.close(); <--- session.close();

看明白了吧,Hibernate的JDBCTransaction根本就是conn.commit而已,根本毫无神秘可言.所以用Hibernate的时候,你在程序中不写 Transaction的话,数据库根本就没有反应。

2.JTATransaction


如果你在EJB中使用Hibernate,或者准备用JTA来管理跨Session的长事务,那么就需要使用JTATransaction,先看一个例子:
javax.transaction.UserTransaction tx = new InitialContext().lookup("javax.transaction.UserTransaction");

Session s1 = sf.openSession();
...
s1.flush();
s1.close();

...

Session s2 = sf.openSession();
...
s2.flush();
s2.close();

tx.commit();


这是标准的使用JTA的代码片断,Transaction是跨Session的,它的生命周期比Session要长。

但是你现在是否看到了什么问题? 仔细想一下,Hibernate Transaction是从Session中获得的,tx = session.beginTransaction(),最后要先提交tx,然后再session.close,这完全符合JDBC的 Transaction的操作顺序,但是这个顺序是和JTA的Transactioin操作顺序彻底矛盾的!!! JTA是先启动Transaction,然后启动Session,关闭Session,最后提交Transaction,因此当你使用JTA的 Transaction的时候,那么就千万不要使用Hibernate的Transaction,而是应该像我上面的JTA的代码片断那样使用才行。


总结:

1)在JDBC上使用Hibernate
必须写上Hibernate Transaction代码,否则数据库没有反应。此时Hibernate的Transaction就是Connection.commit而已

2).在JTA上使用Hibernate
写JTA的Transaction代码,不要写Hibernate的Transaction代码,否则程序会报错.

你可能感兴趣的:(Hibernate,jdbc,ejb)