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

Posted

技术标签:

【中文标题】整个类的事务注释+不包括单个方法【英文标题】:Transactional annotation on whole class + excluding a single method 【发布时间】:2013-08-16 11:46:20 【问题描述】:

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

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

我的问题是我可以在此方法中添加注释以将其标记为“非事务性”吗?还是我应该开始将此类中的每个方法标记为“事务性”,不包括此方法(大量工作)

谢谢。

【问题讨论】:

你试过@Transactional(propagation=NOT_SUPPORTED)吗? 【参考方案1】:

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

你可以找到所有的传播策略here。

【讨论】:

它帮助我解决了非工作“readOnly = true”的问题 建议 NOT_SUPPORTED 或 NEVER 选项并不是一个彻底的答案。开发人员应该非常小心地使用它,因为它可能会在运行时导致意外异常。如果不支持事务暂停,NOT_SUPPORTED 选项可能不起作用(请参阅 javadoc)。如果在事务中意外调用该方法,则永远不会抛出异常。开发人员应该考虑 SUPPORTS 选项,因为它在任何地方都可以正常工作。除非 NEVER 是故意的。【参考方案2】:

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

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

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

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

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

让方法的行为 exacty 就像根本没有用 @Transactional 注释一样的唯一方法是按照 OP 的建议进行操作:不要注释类,而是注释所有其他类方法,但对于大多数用途来说,这不是必需的,使用 Propagation.SUPPORTS 就足够了。

【讨论】:

以上是关于整个类的事务注释+不包括单个方法的主要内容,如果未能解决你的问题,请参考以下文章

Transactional ejb 事务陷阱

Mysql-锁

Intellij IDEA 里面怎么在实现父类方法的时候不带出父类的注释

混合单个实例,而不是类

对多个方法 C# 使用单个事务?

如何查找对类的所有对象的所有调用