zyljjf 2012-03-27
http://blog.csdn.net/lifaming15/article/details/2564660
Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBCTransaction的封装,或者是JTATransaction的封装,下面我们详细的分析:Hibernate可以配置为JDBCTransaction或者是JTATransactHibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBCTransaction的封装,或者是JTATransaction的封装,下面我们详细的分析:
Hibernate可以配置为JDBCTransaction或者是JTATransaction,这取决于你在hibernate.properties中的配置:
#hibernate.transaction.factory_classnet.sf.hibernate.transaction.JTATransactionFactory
#hibernate.transaction.factory_classnet.sf.hibernate.transaction.JDBCTransactionFactory
如果你什么都不配置,默认情况下使用JDBCTransaction,如果你配置为:
hibernate.transaction.factory_classnet.sf.hibernate.transaction.JTATransactionFactory
将使用JTATransaction
不管你准备让Hibernate使用JDBCTransaction,还是JTATransaction,我的忠告就是什么都不配,将让它保持默认状态,如下:
#hibernate.transaction.factory_classnet.sf.hibernate.transaction.JTATransactionFactory
#hibernate.transaction.factory_classnet.sf.hibernate.transaction.JDBCTransactionFactory
在下面的分析中我会给出原因。
一、JDBCTransaction
看看使用JDBCTransaction的时候我们的代码例子:
Sessionsession=sf.openSession();
Transactiontx=session.beginTransactioin();
...
session.flush();
tx.commit();
session.close();
这是默认的情况,当你在代码中使用Hibernate的Transaction的时候实际上就是JDBCTransaction。那么JDBCTransaction究竟是什么东西呢?来看看源代码就清楚了:
Hibernate2.0.3源代码中的类
net.sf.hibernate.transaction.JDBCTransaction:
publicvoidbegin()throwsHibernateException{
...
if(toggleAutoCommit)session.connection().setAutoCommit(false);
...
}
这是启动Transaction的方法,看到connection().setAutoCommit(false)了吗?是不是很熟悉?
再来看
publicvoidcommit()throwsHibernateException{
...
try{
if(session.getFlushMode()!=FlushMode.NEVER)session.flush();
try{
session.connection().commit();
committed=true;
}
...
toggleAutoCommit();
}
这是提交方法,看到connection().commit()了吗?下面就不用我多说了,这个类代码非常简单易懂,通过阅读使我们明白Hibernate的Transaction都在干了些什么?我现在把用Hibernate写的例子翻译成JDBC,大家就一目了然了:
Connectionconn=...;
…..
//把隔离级别设置为4
<propertyname="”"hibernate.connection.isolation>4</property>
……
在开始一个事务之前,Hibernate从配置文件中获得隔离级别的值。
9.3.4在Hibernate中使用JDBC事务
Hibernate对JDBC进行了轻量级的封装,它本身在设计时并不具备事务处理功能。Hibernate将底层的JDBCTransaction或JTATransaction进行了封装,再在外面套上Transaction和Session的外壳,其实是通过委托底层的JDBC或JTA来实现事务的处理功能的。
要在Hibernate中使用事务,可以在它的配置文件中指定使用JDBCTransaction或者JTATransaction。在hibernate.properties中,查找“transaction.factory_class”关键字,得到以下配置:
#hibernate.transaction.factory_classorg.hibernate.transaction.JTATransactionFactory
#hibernate.transaction.factory_classorg.hibernate.transaction.JDBCTransactionFactory
Hibernate的事务工厂类可以设置成JDBCTransactionFactory或者JTATransactionFactory。如果不进行配置,Hibernate就会认为系统使用的事务是JDBC事务。
在JDBC的提交模式(commitmode)中,如果数据库连接是自动提交模式(autocommitmode),那么在每一条SQL语句执行后事务都将被提交,提交后如果还有任务,那么一个新的事务又开始了。
Hibernate在Session控制下,在取得数据库连接后,就立刻取消自动提交模式,即Hibernate在一个执行Session的beginTransaction()方法后,就自动调用JDBC层的setAutoCommit(false)。如果想自己提供数据库连接并使用自己的SQL语句,为了实现事务,那么一开始就要把自动提交关掉(setAutoCommit(false)),并在事务结束时提交事务。
使用JDBC事务是进行事务管理最简单的实现方式,Hibernate对于JDBC事务的封装也很简单。下面是一个在Hibernate中使用JDBC事务的例子:
try{
Sessionsession=HibernateUtil.currentSession();
Transactiontx=session.beginTransaction();//在默认情况下,开启一个JDBC事物
for(inti=0;i
…..
<propertyname="”"hibernate.transaction.factory_class>
org.hibernate.transaction.JTATransactionFactory
</property>
……
下面是一个应用JTA事务的例子:
javax.transaction.UserTransactiontx=null;
tx=newinitialContext().lookup(”javax.transaction.UserTransaction”);
tx.begin();
Sessions1=sf.openSession();
……
s1.flush();s1.close();
Sessions2=sf.openSession();
……
s2.flush();s2.close();
tx.commit();