文档章节

使用@Transactional(SUPPORTS)和不加@Transactional 有什么区别?

MiaoXG
 MiaoXG
发布于 2016/06/27 10:31
字数 1138
阅读 307
收藏 2

Spring 的事务传播机制中 Propagation.SUPPORTS 级别的意义是,如果当前环境有事务,就加入到当前事务;如果没有事务,就以非事务的方式执行。从这个说明来看,使用这个级别和不加@Transaction注解也没什么不一样,找 API 看一下,枚举 Propagation 的 SUPPORTS 项如下:

Support a current transaction, execute non-transactionally if none exists. Analogous to EJB transaction attribute of the same name.

Note: For transaction managers with transaction synchronization, PROPAGATION_SUPPORTS is slightly different from no transaction at all, as it defines a transaction scope that synchronization will apply for. As a consequence, the same resources (JDBC Connection, Hibernate Session, etc) will be shared for the entire specified scope. Note that this depends on the actual synchronization configuration of the transaction manager.

See Also:AbstractPlatformTransactionManager.setTransactionSynchronization(int)

除了意义的说明,文档中还有一个 Note: 对于设置了 transaction synchronization 的事务管理器,两种方式有微小的不同,即使用@Transactional(propagation = Propagation.SUPPORTS) 方式会定义一个事务作用域,等等... 但是还是没理解有什么用,继续看一下See 指向的地方

/**
 * Set when this transaction manager should activate the thread-bound
 * transaction synchronization support. Default is "always".
 * <p>Note that transaction synchronization isn't supported for
 * multiple concurrent transactions by different transaction managers.
 * Only one transaction manager is allowed to activate it at any time.
 * @see #SYNCHRONIZATION_ALWAYS
 * @see #SYNCHRONIZATION_ON_ACTUAL_TRANSACTION
 * @see #SYNCHRONIZATION_NEVER
 * @see TransactionSynchronizationManager
 * @see TransactionSynchronization
 */
public final void setTransactionSynchronization(int transactionSynchronization) {
   this.transactionSynchronization = transactionSynchronization;
}

也没看出什么,按照See的指示,去看 TransactionSynchronization,

package org.springframework.transaction.support;

import java.io.Flushable;

/**
 * Interface for transaction synchronization callbacks.
 * Supported by AbstractPlatformTransactionManager.
 *
 * <p>TransactionSynchronization implementations can implement the Ordered interface
 * to influence their execution order. A synchronization that does not implement the
 * Ordered interface is appended to the end of the synchronization chain.
 *
 * <p>System synchronizations performed by Spring itself use specific order values,
 * allowing for fine-grained interaction with their execution order (if necessary).
 *
 * @author Juergen Hoeller
 * @since 02.06.2003
 * @see TransactionSynchronizationManager
 * @see AbstractPlatformTransactionManager
 * @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER
 */
public interface TransactionSynchronization extends Flushable {

   /** Completion status in case of proper commit */
   int STATUS_COMMITTED = 0;

   /** Completion status in case of proper rollback */
   int STATUS_ROLLED_BACK = 1;

   /** Completion status in case of heuristic mixed completion or system errors */
   int STATUS_UNKNOWN = 2;


   /**
    * Suspend this synchronization.
    * Supposed to unbind resources from TransactionSynchronizationManager if managing any.
    * @see TransactionSynchronizationManager#unbindResource
    */
   void suspend();

   /**
    * Resume this synchronization.
    * Supposed to rebind resources to TransactionSynchronizationManager if managing any.
    * @see TransactionSynchronizationManager#bindResource
    */
   void resume();

   /**
    * Flush the underlying session to the datastore, if applicable:
    * for example, a Hibernate/JPA session.
    * @see org.springframework.transaction.TransactionStatus#flush()
    */
   @Override
   void flush();

   /**
    * Invoked before transaction commit (before "beforeCompletion").
    * Can e.g. flush transactional O/R Mapping sessions to the database.
    * <p>This callback does <i>not</i> mean that the transaction will actually be committed.
    * A rollback decision can still occur after this method has been called. This callback
    * is rather meant to perform work that's only relevant if a commit still has a chance
    * to happen, such as flushing SQL statements to the database.
    * <p>Note that exceptions will get propagated to the commit caller and cause a
    * rollback of the transaction.
    * @param readOnly whether the transaction is defined as read-only transaction
    * @throws RuntimeException in case of errors; will be <b>propagated to the caller</b>
    * (note: do not throw TransactionException subclasses here!)
    * @see #beforeCompletion
    */
   void beforeCommit(boolean readOnly);

   /**
    * Invoked before transaction commit/rollback.
    * Can perform resource cleanup <i>before</i> transaction completion.
    * <p>This method will be invoked after {@code beforeCommit}, even when
    * {@code beforeCommit} threw an exception. This callback allows for
    * closing resources before transaction completion, for any outcome.
    * @throws RuntimeException in case of errors; will be <b>logged but not propagated</b>
    * (note: do not throw TransactionException subclasses here!)
    * @see #beforeCommit
    * @see #afterCompletion
    */
   void beforeCompletion();

   /**
    * Invoked after transaction commit. Can perform further operations right
    * <i>after</i> the main transaction has <i>successfully</i> committed.
    * <p>Can e.g. commit further operations that are supposed to follow on a successful
    * commit of the main transaction, like confirmation messages or emails.
    * <p><b>NOTE:</b> The transaction will have been committed already, but the
    * transactional resources might still be active and accessible. As a consequence,
    * any data access code triggered at this point will still "participate" in the
    * original transaction, allowing to perform some cleanup (with no commit following
    * anymore!), unless it explicitly declares that it needs to run in a separate
    * transaction. Hence: <b>Use {@code PROPAGATION_REQUIRES_NEW} for any
    * transactional operation that is called from here.</b>
    * @throws RuntimeException in case of errors; will be <b>propagated to the caller</b>
    * (note: do not throw TransactionException subclasses here!)
    */
   void afterCommit();

   /**
    * Invoked after transaction commit/rollback.
    * Can perform resource cleanup <i>after</i> transaction completion.
    * <p><b>NOTE:</b> The transaction will have been committed or rolled back already,
    * but the transactional resources might still be active and accessible. As a
    * consequence, any data access code triggered at this point will still "participate"
    * in the original transaction, allowing to perform some cleanup (with no commit
    * following anymore!), unless it explicitly declares that it needs to run in a
    * separate transaction. Hence: <b>Use {@code PROPAGATION_REQUIRES_NEW}
    * for any transactional operation that is called from here.</b>
    * @param status completion status according to the {@code STATUS_*} constants
    * @throws RuntimeException in case of errors; will be <b>logged but not propagated</b>
    * (note: do not throw TransactionException subclasses here!)
    * @see #STATUS_COMMITTED
    * @see #STATUS_ROLLED_BACK
    * @see #STATUS_UNKNOWN
    * @see #beforeCompletion
    */
   void afterCompletion(int status);

}

从这看出点意思, spring 框架执行事务的过程中可以执行回调。而 AbstractPlatformTransactionManager.setTransactionSynchronization(int)方法就是控制是否可以执行的开关。 所以,使用 Propagation.SUPPORTS 方式 和 不使用 @Transaction 注解有两点区别:

  1. 前者的方法可以获取和当前事务环境一致的 Connection 或 Session,而后者肯定是新的;
  2. 前者可以在挂起事务、恢复事务的时侯执行回调方法,而后者做不到。

ps:并没有看全整个流程的源码,再看时候进行补充!

© 著作权归作者所有

MiaoXG
粉丝 2
博文 19
码字总数 17098
作品 0
朝阳
程序员
私信 提问
java @Transactional 传播行为

注意这里写的是spring的Transactional,不是javax下面的Transactional.... 尽量使用spring下面的Transactional,虽然我也不知道这两者本质区别是什么.... 看一篇博客,觉得写得很不错就copy过...

朝如青丝暮成雪
04/24
20
0
Spring @Transactional 事务陷阱

Spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。 Spring默认情况下会对运行期例外(RunTimeException...

恋空御月
2016/07/26
43
0
Spring @Transactional (一) 加强版

spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。 Spring默认情况下会对运行期例外(RunTimeException...

商者
2016/12/20
17
0
Spring 注解@Transactional

Spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。 Spring默认情况下会对运行期例外(RunTimeException...

宋志刚
2013/11/18
298
0
spring Transactional(转)

经常用到老搞混,从网上摘了点记录下来。 // 业务方法需要在一个事物中运行,如果方法运行时,已经存在一个事物中, // 那么加入该事物,否则为自己创建一个新事物。 @Transactional(propaga...

blooms
2012/09/13
326
0

没有更多内容

加载失败,请刷新页面

加载更多

3_数组

3_数组

行者终成事
今天
7
0
经典系统设计面试题解析:如何设计TinyURL(二)

原文链接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
今天
7
0
使用logstash同步MySQL数据到ES

概述   在生成业务常有将MySQL数据同步到ES的需求,如果需要很高的定制化,往往需要开发同步程序用于处理数据。但没有特殊业务需求,官方提供的logstash就很有优势了。   在使用logstas...

zxiaofan666
今天
10
0
X-MSG-IM-分布式信令跟踪能力

经过一周多的鏖战, X-MSG-IM的分布式信令跟踪能力已基本具备, 特点是: 实时. 只有要RX/TX就会实时产生信令跟踪事件, 先入kafka, 再入influxdb待查. 同时提供实时sub/pub接口. 完备. 可以完整...

dev5
今天
7
0
OpenJDK之CyclicBarrier

OpenJDK8,本人看的是openJDK。以前就看过,只是经常忘记,所以记录下 图1 CyclicBarrier是Doug Lea在JDK1.5中引入的,作用就不详细描述了,主要有如下俩个方法使用: await()方法,如果当前线...

克虏伯
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部