事务在Hibernate以及JPA中的应用(一)

首先需要声明的是,hibernate本身没有事务功能。它只是借助JDBC事务,或者JTA事务来实现事务的管理,它只是封装了事务的使用方法。一般事务控制定界到service层,但是为了方便,以下的代码将事务代码放在Dao层。事务在Hiibernate中的应用具体可以分为一下三部分:



1 JDBC事务在Hibernate的应用。如果我们系统不需要分布式的话,那么就可以采用JDBC事务来提供事务服务。要想在Hibernate里使用 JDBC事务,我们必须要配置如下属性:hibernate.transaction.factory_class=org.hiberante.transaction.JDBCTransactionFactory.

在此种情况下典型的编码方式如下:
Java代码

public class XXXDao ...{

Session session ;
Transaction tx ;

public void crudOperation(){

try{

session = HibernateUtil.getCurrentSession();
tx = session.beginTransaction();
//完成具体的CRUD操作。
tx.commit();

}catch(RuntimeException e){

tx.rollback();
}finally{

this.getSession().close();
}

}
}

public class XXXDao ...{

Session session ;
Transaction tx ;

public void crudOperation(){

try{

session = HibernateUtil.getCurrentSession();
tx = session.beginTransaction();
//完成具体的CRUD操作。
tx.commit();

}catch(RuntimeException e){

tx.rollback();
}finally{

this.getSession().close();
}

}
}

在此种情况下,Hibernate的数据库连接可以由容器来管理,也可以自己管理一个数据库连接池,并且只有当事务开始的时候才获得 connection.需要注意的是,tx.beginTransaction(),此语句实际上是将获得connection的自动提交模式关闭,也就是connection.setAutoCommit(false)。



2 JTA事务在Hibernate中的应用。如果要想使用JTA事务提供的分布式事务服务,那么必须要做以下事情:

首先,需要确保相对应的JDBC驱动程序支持XAResource接口,因为只有支持此接口的JDBC Driver才能纳入JTA事务管理器的管理。

其次,需要更改配置如下:

hibernate.transaction.factory_class=org.hiberante.transaction.JTATransactionFactory.

hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup.(此配置根据自己的JavaEE AS来配置).

确保以上两个条件后,就需要考虑选择JTA provider了,是选择JavaEE服务器来提供JTA服务呢,还是通过开源的JTA组件来提供服务。如果采用开源的组件的话,可以采用如JBoss 的JTA组件等。如果采用JavaEE服务器的话,则可以直接受益与Application server提供的JTA服务了。

需要注意的是在这种情况下,hibernate不再管理数据库连接池了,它需要通过JNDI来获取JTA提供者暴漏的连接池服务。

在此种模式下,编程模型可以采用如下两种:

1)利用hibernate的Transaction接口。典型的代码如下:


Java代码

public class XXXDao ...{

Session session ;
Transaction tx ;

public void crudOperation(){

try{

session = HibernateUtil.getCurrentSession();
tx = session.beginTransaction();
//完成具体的CRUD操作。
tx.commit();

}catch(RuntimeException e){

tx.rollback();
}finally{

this.getSession().close();
}

}
}

public class XXXDao ...{

Session session ;
Transaction tx ;

public void crudOperation(){

try{

session = HibernateUtil.getCurrentSession();
tx = session.beginTransaction();
//完成具体的CRUD操作。
tx.commit();

}catch(RuntimeException e){

tx.rollback();
}finally{

this.getSession().close();
}

}
}

如果采用Hibernate的原生接口的话,那么不需要应用程序flush session和关闭session了,因为在模型下,hibernate内部会在事务提交的时候自动flush和close session.但是这样做不好的地方就是将应用程序绑定到hiberante原生(Native)接口,不便于系统的移植,所以为了方便系统移植,以及将事务服务的提供留给应用程序部署者来完成,我们可以采用standard JTA接口。JTA编程接口典型的代码如下:
Java代码

public class XXXDao ...{

Session session ;
UserTransaction utx = (UserTransaction)ServiceLocator.getUserTransaction("JNDIName") ;

public void crudOperation(){

try{

utx.begin():
session = HibernateUtil.getCurrentSession();

//完成具体的CRUD操作。
utx.commit();
session.flush();//此时需要程序来flush session

}catch(RuntimeException e){

utx.rollback();
//日志记录等
}finally{

this.getSession().close();
}

}
}

public class XXXDao ...{

Session session ;
UserTransaction utx = (UserTransaction)ServiceLocator.getUserTransaction("JNDIName") ;

public void crudOperation(){

try{

utx.begin():
session = HibernateUtil.getCurrentSession();

//完成具体的CRUD操作。
utx.commit();
session.flush();//此时需要程序来flush session

}catch(RuntimeException e){

utx.rollback();
//日志记录等
}finally{

this.getSession().close();
}

}
}



此时值得注意的时,需要应用程序来刷新session,如果想要激活自动刷新和自动关闭session的功能,需要配置如下两个属性:

* hibernate.transaction.flush_before_completion和 hibernate.transaction.auto_close_session为true.这样以来当JTA事务提交和回滚的时候 Hibernate就会自动刷新和关闭session.



如果觉得以上代码不够美观的话,那是正常的,因为代码中充斥着try,catch语句,以及将事务处理的代码侵入到了业务代码中。如何避免这些烦人的try ,catch语句,以及事务处理代码,就需要比较流行的AOP来解决。如果采用AOP的话,建议采用现成的AOP框架来实现,比如spring就支持 hibernate的声明式事务管理,当然也可以采用代理等模式来自己实现,看系统需要和个人爱好。



3.采用容器管理事务(CMT).如果采用JavaEE AS的话,我们就可以直接使用EJB容器提供的声明式事务管理功能了。在此种模式下,其实底层事务还是JTA,不过事务控制是由容器来控制,应用程序只需要负责业务核心就OK了。如果采用CMT的话,可以通过session bean来封装 hibernate session,这样可以通过EJB的Annotation来注解业务方法,这样以来就不需要我们关心事务代码了,只需要配置支持XA 标准的数据源就好了。不过此时的事务工厂类要配置为CMTTransactionFactory.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值