@Transactional如何影响Hibernate中的当前会话?

这是大多数DAO中使用的典型设置:

@Transactional @Repository public class DAO { @Autowired SessionFactory sessionFactory; public void save(Entity o) { sessionFactory.getCurrentSession().save(o); } public Entity load(int id) { return (Entity)sessionFactory.getCurrentSession().get(Entity.class, id); } } 

我看到只调用了getCurrentSession() ,没有openSession或者close

因此,当我从load返回实体时,它不在会话中,懒惰的集合无法加载。 同样,保存似乎总是冲洗!

来自spring的@Transactional注释是否完成了打开和关闭会话和事务的魔力?

在Spring中,由@Transactional划分的业务事务与hibernate Session之间存在一对一的对应关系。

也就是说,当通过调用@Transactional方法开始业务事务时,会创建hibernate会话(TransactionManager可能会延迟实际创建,直到首次使用该会话)。 该方法完成后,将提交或回滚业务事务,从而关闭hibernate会话。

在您的情况下,这意味着调用DAO方法将开始一个新事务(除非事务正在进行中),退出DAO方法将结束它,这将关闭hibernate会话,也会刷新它,并提交或滚动返回相应的hibernate事务,然后提交或回滚相应的JDBC事务。

至于这是典型用法,hibernate文档称之为每次操作会话反模式 。 同样,Spring参考手册中@Transactional所有示例都放在业务服务方法(或类)上,而不是存储库。

Spring为使用@Transactional注释的bean提供事务建议。 Spring事务为以下六个属性提供支持,这六个属性决定了事务的行为

1.isolation,2.no-rollback-for,3.propagation,4.read-only,5.rollback-for,6.timeout。

@Transactional可以启动新事务,也可以根据其传播属性值加入现有事务上下文。

@Transactional上下文中, getCurrentSession()方法创建新的Session对象(如果它不存在)或返回附加到当前事务的Session。 OpenSession()方法始终创建新会话。 @Transactional可以帮助您扩展Session范围。

会话在执行getCurrentSession()时首次打开,并在事务结束时关闭,并在事务提交之前刷新。

在Spring中,如果我们在非事务上下文中使用getCurrentSession() ,我们会得到一个exception。