您的位置:首页 > 编程语言 > Java开发

Spring4+Hibernate4配置注解事务控制

2015-04-03 11:36 351 查看
一、配置注解事务管理

在hibernate的sessionFactory配置后面添加如下配置信息

<!-- 配置事务管理器bean,使用HibernateTransactionManager事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<!-- 为事务管理器注入sessionFactory" -->
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 注解实现事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />


修改hibernate的sessionFactory配置的属性:

<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>


使用spring整合hibernate,并由spring来管理事务时,如果这个属性值设置为thread,那么使用session.getCurrentSession()获取session,调用get、load等方法时,会报异常:org.hibernate.HibernateException: is not valid without active transaction 。可以参考:http://blog.csdn.net/z69183787/article/details/8768421

二、使用注解@Transactional开启spring事务管理

@Transactional默认只有当方法中抛出unchecked的runtimeException时,才会进行回滚,抛出需捕获的Exception异常是不能进行回滚的。如下例子所示:

@Transactional
public void addUser() throws Exception {
User add = new User();
add.setNickName("asd");
add.setPassword("123456");
add.setUrlID("asdadsad");
add.setUserName("12222");
userDao.add(add);
throw new Exception();
}


执行这个方法后,添加用户的操作会被执行,不会进行回滚。

如果将代码改成如下所示:

@Transactional
public void addUser() {
User add = new User();
add.setNickName("asd");
add.setPassword("123456");
add.setUrlID("asdadsad");
add.setUserName("12222");
userDao.add(add);
throw new RuntimeException();
}


就会进行回滚。

值得注意的是如果你在方法中使用try catch捕获了异常,那么事务也不会进行回滚。例如:

@Transactional
public void addUser() {
try {
User add = new User();
add.setNickName("asd");
add.setPassword("123456");
add.setUrlID("asdadsad");
add.setUserName("12222");
userDao.add(add);
throw new RuntimeException();
} catch (Exception e) {
e.printStackTrace();
}
}


事务不会回滚。如果想要回滚,可以在catch中再抛出RuntimeException。

上面描述的是@Transactional默认处理的异常,@Transactional有相应的属性可以设置,例如控制@Transactional处理那些异常等等,具体可以参考spring官方文档。

三、hibernate的SessionFactory的getCurrentSession和openSession

getCurrentSession方法是获取当前上下文的session,该方法必须获取的session进行相应操作时必须在一个事务中进行,否则会报异常org.hibernate.HibernateException: is not valid without active。这个方法获取的session会自动进行关闭。

openSession方法是开启一个新的session,不需要在事务中执行,并且获取的session需要手动进行关闭。

所以在上述配置中,如果方法使用注解@Transactional,就需要使用getCurrentSession。反之,不是使用注解@Transactional,就是不进行事务控制,就是应该使用openSession方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息