整个类的事务注释+不包括单个方法

Urb*_*leg 19 spring hibernate jpa transactions jta

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

虽然我在该类中有一个不应该注释为的方法@Transactional.

我的问题是,我可以在此方法中添加注释以将其标记为"非事务性"吗?或者我应该开始将此类中的每个单一方法标记为"事务性",不包括此方法(很多工作)

谢谢.

Sot*_*lis 30

有不同的事务传播策略可供使用.这些存在于枚举中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
Run Code Online (Sandbox Code Playgroud)

因此,使用其中任何一个来注释类中的方法.

@Transactional
public class MyTransactionalClass { 
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void nonTransactionalMethod() {...}
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到所有传播策略.

  • 建议使用NOT_SUPPORTED或NEVER选项并不是一个彻底的答案.开发人员应该非常小心地使用它,因为它可能会在运行时导致意外的异常.如果不支持事务暂停,则NOT_SUPPORTED选项可能不起作用(请参阅javadoc).如果在事务中意外调用该方法,则永远不会抛出异常.开发人员应该考虑SUPPORTS选项,因为它可以在任何被调用的地方愉快地工作.除非从来没有意图. (2认同)

Pep*_*itz 5

很抱歉回答一个六年前的问题,但我注意到接受的答案实际上并没有回答这个问题。问题是如何让方法表现得好像根本没有注释一样@Transactional。如果有,这种方法将参与事务,如果没有,则以非事务方式执行。它不会暂停现有的交易,也不会在有交易的情况下拒绝执行,其中之一将是接受答案的结果。

要使用的传播是Propagation.SUPPORTS(换句话说,用 注释方法@Transactional(propagation = SUPPORTS)。如果有,这将参与事务,如果没有,则以非事务方式执行,就像未注释的方法一样。

并不是说根据 Javadoc,它与根本没有注释并不完全相同@Transactional。它说:

支持当前事务,如果不存在则以非事务方式执行。类似于同名的 EJB 事务属性。

注意:对于具有事务同步的事务管理器,SUPPORTS 与根本没有事务略有不同,因为它定义了同步将应用的事务范围。因此,将在整个指定范围内共享相同的资源(JDBC 连接、Hibernate 会话等)。请注意,这取决于事务管理器的实际同步配置。

使该方法表现得像完全没有注释一样的唯一方法@Transactional是按照 OP 的建议进行操作:不要注释该类,而是注释所有其他方法,但对于大多数不需要的用途并使用Propagation.SUPPORTS就足够了。