Spring-Hibernate Transactional只读传播

时间:2017-01-29 13:00:20

标签: java spring hibernate

我读到了有关事务传播和只读的信息 但是有些东西对我来说并不清楚。

假设我有这段代码:

@Transactional(readOnly = true)
public void first() {
    second();
}

@Transactional
public void second() {
    //do Something
}

会发生什么? 是否会暂停第一个方法,因为它无法刷新/提交,第二个方法需要这样做吗?
或者也许'只读'也会传播到内部呼叫? (因为我处于'必需'传播模式)?

1 个答案:

答案 0 :(得分:1)

您在progagation注释上定义了一个名为@Transactional的功能。

有两个选项可以适应内部交易场景

<强> NESTED

  

如果存在当前事务,则在嵌套事务中执行,   表现得像PROPAGATION_REQUIRED其他。没有类似的功能   在EJB中。注意:实际创建嵌套事务只能起作用   在特定的交易经理。开箱即用,这仅适用于   在处理JDBC 3.0时,JDBC DataSourceTransactionManager   驱动程序。一些JTA提供程序也可能支持嵌套事务。

REQUIRES_NEW

  

PROPAGATION_REQUIRES_NEW开始一个新的,独立的&#34;内部&#34;交易   对于给定的范围。此事务将被提交或回滚   完全独立于外部交易,拥有自己的交易   隔离范围,它自己的一组锁等。外部事务将   在内部开始时被暂停,并且恢复一次   内心已完成。

由于外部事务被标记为readOnly,因此NESTED选项没有意义,因为内部事务的提交依赖于外部事务..而外部不允许任何更改发生..

所以在我看来只有

@Transaction(propagation = Propagation.REQUIRES_NEW)
public void second(..)

在这种情况下有意义。

只是为了强调..这应该在理论上有用..有许多因素需要考虑..数据库功能,库版本等......你必须做一些进一步的测试,但希望这能给你一个想法。

<强>更新

要绕过这个..尝试制作另一个更高级别的服务,这不是事务性的..那么你可以注入较低级别的服务并按顺序执行调用而不会出现嵌套事务问题:

    @Service
    public class FacadeService{

       @Autowired 
       private TransactionalService service;

       public void perform(..){

            service.first(); 
            service.second();
            ...
       }
}