【问题标题】:How does @Transactional influence current session in Hibernate?@Transactional 如何影响 Hibernate 中的当前会话?
【发布时间】:2014-07-12 07:15:13
【问题描述】:

这是大多数 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 注释本身是否具有打开和关闭会话和事务的魔力?

【问题讨论】:

  • 是的,看看这个答案stackoverflow.com/questions/10680364/…
  • @ShadowRay 嘿,谢谢。该链接很好,但与@Transactional 无关。您是否能够描述当您连接 sessionFactory,然后调用 DAO 的方法时会发生什么?

标签: java database spring hibernate


【解决方案1】:

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

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

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

至于这是典型的用法,hibernate 文档称之为session-per-operation anti pattern。同样,spring 参考手册中@Transactional 的所有示例都放在业务服务方法(或类)上,而不是存储库。

【讨论】:

    【解决方案2】:

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

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

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

    在@Transactionalcontext 中,getCurrentSession() 方法如果不存在则创建新的 Session 对象,或者返回附加到当前事务的 Session。 OpenSession() 方法总是创建新会话。 @Transactional 帮助您扩展Session 的范围。

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

    在 Spring 中,如果我们在非事务性上下文中使用 getCurrentSession(),则会出现异常。

    【讨论】:

    • 好的,谢谢!!所以在@Transactional 类中,当我输入一个方法时,事务已经在进行中,对吧?一旦我离开该方法,它就会被提交?那么,从 Hibernate 的角度来看,当我离开该方法时,实体的更改会刷新到 DB,并且实体会分离?
    • 并非总是如此。这取决于您的传播模式和隔离级别。例如PROPAGATION_MANDATORY = 如果没有正在进行的现有事务,方法总是在事务中启动。通过使用传播模式,我们可以在一个事务中运行不同的方法,即@Transaction。
    猜你喜欢
    • 2018-01-22
    • 2017-12-10
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2021-12-15
    • 2015-05-28
    相关资源
    最近更新 更多