首页 > 解决方案 > PlatformTransactionManager 如何在 Spring Transaction 内部工作?

问题描述

当我尝试执行交易时......我的代码看起来像这样......

public class MyService {
    private FirstDao firstDao;
    private SecondDao secondDao;
    private SomeotherDao someotherDao;

    @Transactional
    public void firstMethod() {
        // performing some operation using firstDao
        try {
            secondMethod();
        } catch (Exception e) {
            // catching the exception
        }
    }

    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void secondMethod() {
        // performing some operation using secondDao
        // some exception throws
    }

    @Transactional
    public void someOtherMethod() {
        // some other operation using someotherDao
    }
}

由于AOP是在 Spring 中执行事务的原因。对于每个操作(基于传播级别),我认为它将创建一个适当的事务管理器,例如DataSourceTransactionManager,等等,

在上面的代码中,当我尝试调用firstMethod它时,内部调用的secondMethod是同一个 bean。如果 . 抛出了一些异常secondMethod,它不应该反映或在提交firstMethod. 但是,如果发生问题,secondMethod我们也无法提交,firstMethod因为它们共享相同TransactionManager

但是根据这个线程为什么即使在 Spring 服务类中的第二个方法中传播 = Propagation.REQUIRES_NEW 时事务也会回滚?

我的理解是通过在其他一些 bean/类中编写secondMethod将解决这个问题,因为TransactionManger这两种方法都使用相同的方法。

我不认为这是内部发生的事情。如果发生这种情况,MyService 类中的任何方法都会发生异常,其他所有方法也会失败。

有人可以解释生成代理时代码的样子吗?

这就是我的想法..

public class MyService {

    PlatformTransactionManager platformTransactionManager;

    private FirstDao firstDao;
    private SecondDao secondDao;
    private SomeotherDao someotherDao;

    @Transactional
    public void firstMethod() {
        platformTransactionManager = new DataSourceTransactionManager();
        // performing some operation using firstDao
        try {
            secondMethod();
        } catch (Exception e) {
            // catching the exception
        }

        // if no problem
        platformTransactionManager.commit(status);
        // else
        platformTransactionManager.rollback(status);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void secondMethod() {
        platformTransactionManager = new DataSourceTransactionManager();
        // performing some operation using secondDao

        // if no problem
        platformTransactionManager.commit(status);
        // else
        platformTransactionManager.rollback(status);
    }

    @Transactional
    public void someOtherMethod() {
        platformTransactionManager = new DataSourceTransactionManager();
        // performing some operation using someotherDao

        // if no problem
        platformTransactionManager.commit(status);
        // else
        platformTransactionManager.rollback(status);
    }
}

如果是上述情况true,那么当secondMethodthrows an时Exception,应该没有问题了firstMethod。但这并没有发生。

那么,代理代码的外观如何,给我一些想法。

注意:我可以通过在其他类中编写 secondMethod 来解决这个问题,但想知道如何在PlatformTransactionManager内部进行管理。

编辑:根据此@Transactional 在方法级别上不起作用 当我们调用firstMethodfirstDAOProxy在我们正在调用的此方法中启动事务时secondMethodsecondDAOProxy将启动事务。secondMethod 传播级别是 REQUIRED_NEW,应该没有问题firstMethod firstDAOProxy,但这不是发生的事情。我的firstMethod事务也失败了。

标签: javadatabasespringspring-aopspring-transactions

解决方案


推荐阅读