是否可以在 Spring 中从非事务方法调用事务方法?
Posted
技术标签:
【中文标题】是否可以在 Spring 中从非事务方法调用事务方法?【英文标题】:Is it possible to invoke transactional method from non transactional method in Spring? 【发布时间】:2015-09-01 08:17:16 【问题描述】:假设我有一个 Repository 类。
@Repository
class MyRepository
@Transactional
void method1 ()
// some logic here
void method2 ()
// some logic here
method1();
// some logic here
是否可以在字符串中做到这一点?它是如何工作的?
【问题讨论】:
该特定示例是自调用,不适用于通常的代理 AOP。 我怎样才能让它发挥作用? 通常控制器是一个调用层服务的非事务类,内部有事务方法是一个好习惯。我看不出有什么问题,如果你的问题需要这种行为,你可以毫无问题地做到这一点。 但是由于@chrylis 描述的原因,我的代码无法正常工作。我相信有一些技巧可以使它与非标准代理机制一起工作。 我认为有一种方法可以通过将@Autowired private ApplicationContext context;
添加到您的存储库中,然后当您从method2
调用method1
时,您可以这样做((MyRepository)context.getBean(getClass())).method1()
。不过我建议不要这样做。
【参考方案1】:
这不起作用,因为这是一个自调用。见Spring @Transaction method call by the method within the same class, does not work?
根据您的应用程序及其职责,您可以为method2()
创建另一个bean。
除此之外,DAO 方法通常不应注解@Transactional
。见Where does the @Transactional annotation belong?
【讨论】:
可以使用 org.springframework.aop.framework.AopContext 使其工作......但建议不要使用它。【参考方案2】:这不起作用,因为当您调用method2
时,该方法将超出@Transaction
的范围。但是您可以通过以下方式应用 hack 并使用 this
从 method1
调用 method2
。
this.method2();
【讨论】:
【参考方案3】:您应该使用自注入从非 Transactional
调用 Transactional
方法,就像在 Spring 中一样,由于 AOP 代理的事情,您不能简单地从同一实例调用 @Transactional
方法
@Repository
class MyRepository
@Autowired
MyRepository selfTxMyRepository;
@Transactional
void method1 ()
// some logic here
void method2 ()
// some logic here
selfTxMyRepository.method1();
// some logic here
在这里查看一些解释:https://vladmihalcea.com/the-open-session-in-view-anti-pattern/
【讨论】:
【参考方案4】:您不能这样做,因为 Spring 包装了将从另一个类(服务)调用的方法。如果您从同一个类中调用带注释的方法,Spring 将什么也不做,因为它无法包装它们。
【讨论】:
以上是关于是否可以在 Spring 中从非事务方法调用事务方法?的主要内容,如果未能解决你的问题,请参考以下文章