整个类上的事务注解 + 排除单个方法

34

我有一个带有@Transactional注释的类(而不是将其标记为其所有方法)。

尽管我在该类中只有一个不应标记为@Transactional的方法。

我的问题是:是否有一个注释可以放在这个方法中,将其标记为“非事务性”?还是我应该开始标记该类中每个单独的方法为“事务性”,但排除掉这个方法(这是很多工作)。

谢谢。


1
你尝试过使用 @Transactional(propagation=NOT_SUPPORTED) 吗? - incomplete-co.de
实际上应该是 @Transactional(propagation = Propagation.NOT_SUPPORTED) - gene b.
2个回答

35

有不同的事务传播策略可供使用,这些都存在于枚举Propagation中。你可能想要使用的策略有:

/**
 * Execute non-transactionally, suspend the current transaction if one exists.
 * Analogous to EJB transaction attribute of the same name.
 * <p>Note: Actual transaction suspension will not work on out-of-the-box
 * on all transaction managers. This in particular applies to JtaTransactionManager,
 * which requires the {@code javax.transaction.TransactionManager} to be
 * made available it to it (which is server-specific in standard J2EE).
 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
 */
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

/**
 * Execute non-transactionally, throw an exception if a transaction exists.
 * Analogous to EJB transaction attribute of the same name.
 */
NEVER(TransactionDefinition.PROPAGATION_NEVER), // maybe not this one

因此,请在您的类中使用以下任何一种方法进行注释。

@Transactional
public class MyTransactionalClass { 
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void nonTransactionalMethod() {...}
}

您可以在此处找到所有传播策略的链接


它帮助我解决了“readOnly = true”无法工作的问题。 - Piotr Sagalara
3
建议使用NOT_SUPPORTED或NEVER选项并不是一个全面的答案。开发者在使用时应非常小心,因为它可能会在运行时引起意外的异常。如果事务暂停不被支持,则NOT_SUPPORTED选项可能无法正常工作(请参阅javadoc)。如果在事务内意外调用了该方法,NEVER将抛出异常。开发者应该考虑使用SUPPORTS选项,因为它可以在任何位置愉快地工作,除非严格要求使用NEVER选项。 - t7tran

12
使用“NOT_SUPPORTED”或“NEVER”的传播方式并没有真正回答问题。问题是如何使一个方法的行为就像没有使用“@Transactional”注解一样。这样的方法将在存在事务时参与事务,如果没有事务,则以非事务方式执行。它不会挂起现有的事务,也不会拒绝执行,这是接受的答案的结果之一。
要使用的传播方式是“Propagation.SUPPORTS”(换句话说,用“@Transactional(propagation = SUPPORTS)”注解该方法)。这将在存在事务时参与事务,如果没有事务,则以非事务方式执行,就像一个没有注解的方法一样。
需要注意的是,根据Javadoc的说明,这并不完全等同于没有任何“@Transactional”注解。它说:
支持当前事务,如果不存在事务,则以非事务方式执行。类似于同名的EJB事务属性。
注意:对于具有事务同步的事务管理器,SUPPORTS与没有事务略有不同,因为它定义了同步将应用于的事务范围。因此,相同的资源(JDBC连接、Hibernate会话等)将在整个指定范围内共享。请注意,这取决于事务管理器的实际同步配置。
要使该方法的行为完全与未使用@Transactional注释的方法相同,唯一的方法是按照OP的建议进行操作:不要对类进行注释,而是对所有其他方法进行注释,但对于大多数用途,这是不必要的,使用Propagation.SUPPORTS将足够。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接