我正在玩Spring Hibernate和Postgresql的一些“手动”事务管理
在转向基于aop的事务管理之前,我想尝试一下并了解其工作原理.
@Repository
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {
@Override
public void saveUser(User u) {
Transaction tx = getSession().beginTransaction();
getHibernateTemplate().saveOrUpdate(u);
tx.rollback();
}
}
在这里调用saveUser,我假设保存一个新用户将被回滚.
但是,移动到psql命令行后,用户将保存在表中.
为什么不回滚,我需要配置什么以这种方式进行交易?
编辑;多一点调试似乎表明getHibernateTemplate()使用的不同于getSession()返回的会话(?)
将代码更改为
Transaction tx = getSession().beginTransaction();
getSession().persist(u);
tx.rollback();
并且事务确实被回滚.但我仍然不明白为什么hibernateTemplate会使用/创建一个新会话.
a)您的JDBC驱动程序默认为autocommit = true,并且以某种方式忽略beginTransaction()和rollback()调用;
b)如果您使用的是Spring 3,我相信SessionFactory.getSession()会返回由Spring代理包装的Hibernate Session对象.在Session上设置Spring代理部分是为了处理事务管理,也许它可能会干扰你的手动事务调用?
虽然您当然可以使用AOP范围的代理进行事务管理,但为什么不在服务层方法上使用@Transactional(readOnly = false | true)注释?在您的服务层方法的Spring配置文件中,您需要做的就是添加
请分别参阅有关事务管理和ORM数据访问的Spring参考文档的第10章和第13章:
http://static.springsource.org/spring/docs/3.0.x/reference/index.html
最后,如果您正在使用Spring 3,则可以通过将Spring代理的SessionFactory bean注入DAO代码来消除代码中对Spring Framework的引用 – 不再需要使用HibernateDaoSupport.只需注入SessionFactory,获取当前Session,并根据Hibernate示例使用Hibernate. (如果需要,您可以在同一个应用程序中结合使用HibernateDaoSupport和基于SessionFactory的简单Hibernate代码.)