【问题标题】:Spring Transaction PropagationSpring 事务传播
【发布时间】:2014-06-22 08:18:22
【问题描述】:

我正在尝试理解 Spring Transaction 的概念。如下所示,我必须将数据插入两个不同的数据库(iSeries 和 DB2),但我们的 iSeries 版本不支持两阶段提交。要求是,仅当两个插入都成功时才应提交事务,否则应回滚。

如果我将传播用作 REQUIRED 或 REQUIRES_NEW,我会收到错误“非法尝试使用现有的两阶段资源提交单阶段资源”。

但是,如果我使用 NOT_SUPPORTED 或 SUPPORTS,它可以正常工作(即,如果其中一个插入失败,则事务回滚,否则如果两个插入都成功,它会提交)。

我的理解是,如果 Propagation = SUPPORTS / NOT_SUPPORTED,那么在以下情况下甚至不会启动 Transaction。因此,两次插入都可能在两个不同的数据库中独立发生,如果其中一个失败,整个事务不应回滚。

但是 Propagation = SUPPORTS / NOT_SUPPORTED 按照我的要求工作。有人可以解释一下吗?提前致谢。

@Resource
private SessionFactory db2SessionFactory = null;

@Resource
private SessionFactory iSeriesSessionFactory = null;

@Transactional(propagation = Propagation.REQUIRED)
public void insert()
{
   insertDB1();
   insertDB2();
}

insertDB1()
{
   db2SessionFactory .getCurrentSession().saveOrUpdate(obj1);
}

insertDB2()
{
   iSeriesSessionFactory.getCurrentSession().saveOrUpdate(obj2);
}

【问题讨论】:

    标签: spring transactions propagation


    【解决方案1】:

    JTA 支持两阶段提交事务。检查你是否使用JtaTransactionManager

    当您使用 NOT_SUPPORTEDSUPPORTS 时,它可以正常工作,因为它是非事务性的。见org.springframework.transaction.annotation.Propagationjavadoc。

    【讨论】:

    • 谢谢 Sealter,我会检查 javadoc。
    【解决方案2】:

    好的,我会尽力解释我认为正在发生的事情。我强调,这是我的假设。可能我完全错了。

    首先,我从来不需要为@Transactional 注释指定传播。要求是一个很好的标准。如果您遇到异常,通常是因为您没有正确操作数据库。然而,这可能不是这里的情况,因为我以前从未使用过多个会话工厂。

    当您指定 SUPPORTS 或 NOT_SUPPORTED 时,我认为发生的情况是保存是非事务性发生的 仅仅因为保存是非事务性发生的,并不意味着如果发生某种类型的错误,整个会话不会回滚,因为这显然是正在发生的事情。

    当您使用 REQUIRED 或 REQUIRES_NEW 时,您正在创建一个新事务,每个事务都有自己的 JDBC 连接(显然)但使用相同的事务会话。这就是为什么你得到你的illegal attempt 例外。已为两阶段资源创建了 transactional 会话,但您正尝试使用同一会话保存到单阶段数据库。

    只有当你有 2 个方法注释 @Transactional 时,传播才真正发挥作用,其中一个方法像这样调用另一个方法:

    @Transactional
    public void method1(){
        method2();
    }
    
    @Transactional
    public void method2(){
        //do some transactional stuff here
    }
    

    您的传播级别将决定是否为方法 1 创建新会话、是否为方法 2 使用现有会话、是否为方法 2 创建新会话,或者整个事物是否以非事务方式执行。

    【讨论】:

    • 非常感谢 James 的回答。虽然我部分同意你的分析,但我仍然不清楚 Transactions。但无论如何它也有点棘手。再次感谢!
    猜你喜欢
    • 2017-11-22
    • 2018-01-15
    • 1970-01-01
    • 2016-02-14
    • 2011-09-20
    • 2012-05-27
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    相关资源
    最近更新 更多