java - 在 Spring bean 中启动新事务

标签 java spring transactions

我们有:

@Transactional(propagation = Propagation.REQUIRED)
public class MyClass implementes MyInterface { ...

MyInterface 有一个方法:go()

当 go() 执行时,我们启动一个新事务,该事务在方法完成时提交/回滚 - 这很好。

现在假设在 go() 中,我们调用 MyClass 中的私有(private)方法,该方法具有 @Transactional(propagation = Propagation.REQUIRES_NEW。似乎 Spring “忽略”了 REQUIRES_NEW 注释并且不启动新事务。我相信这是因为 Spring AOP 是在接口(interface)级别(MyInterface)操作的,不会拦截任何对 MyClass 方法的调用。这样对吗?

有没有办法在 go() 事务中启动一个新事务?是调用另一个将事务配置为 REQUIRES_NEW 的 Spring 托管 bean 的唯一方法吗?


更新:添加当客户端执行 go() 时,它们是通过对接口(interface)的引用而不是类来执行的:

@Autowired
MyInterface impl;

impl.go();

最佳答案

来自 Spring 引用 2.5:

When using proxies, the @Transactional annotation should only be applied to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error will be raised, but the annotated method will not exhibit the configured transactional settings.

所以 Spring 会忽略非公共(public)方法上的 @Transactional 注释。

还有,

In proxy mode (which is the default), only 'external' method calls coming in through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the target object calling some other method of the target object, won't lead to an actual transaction at runtime even if the invoked method is marked with @Transactional!

因此,即使您将方法设为 public,从同一类的方法中调用它也不会启动新事务。

可以在事务设置中使用aspectj模式,使事务相关的代码编织在类中,运行时不创建代理。

the reference document了解更多详情。

另一种可能的方法是在类本身中获取类的spring代理并在其上调用方法而不是this:

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class SomeService {

    @Autowired
    private ApplicationContext applicationContext;

    private SomeService  getSpringProxy() {
        return applicationContext.getBean(this.getClass());
    }

    private void doSomeAndThenMore() {
        // instead of
        // this.doSometingPublicly();
        // do the following to run in transaction
        getSpringProxy().doSometingPublicly();
    }

    public void doSometingPublicly() {
        //do some transactional stuff here
    }

}

关于java - 在 Spring bean 中启动新事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3037006/

相关文章:

database - 如何防止事务违反 Datomic 中的应用程序不变量

java - 使用 JSTL forEach 迭代 ArrayList 项

Spring 数据 - "class path resource [org/jboss/resource/adapter/jdbc/vendor/MySQLExceptionSorter.class"

java - 运算符优先级,哪个结果是正确的?

java - jackson : "(although at least one Creator exists): no String-argument constructor/factory method to deserialize"

java - Spring和RESTfull ConcurrentModel不支持null属性值

transactions - 写一个TypeORM@Transaction方法,使用这个方法IDE报错 "Invalid number of arguments, expect 2"

java - Spring 中具有多个事务管理器的多个数据源

java - 如何以最有效的方式在neo4j图中创建一对多关系?

Java 主目录