通过TransactionDefinition接口来学习spring事务的隔离级别和传播特性(4.3.4版本)

通过spring官方包中带的原代码来看spring的事务的5中隔离级别和7种传播特性;    

源码如下:

/*
 * Copyright 2002-2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction;

import java.sql.Connection;

/**
 * Interface that defines Spring-compliant transaction properties.
 * Based on the propagation behavior definitions analogous to EJB CMT attributes.
 *
 * <p>Note that isolation level and timeout settings will not get applied unless
 * an actual new transaction gets started. As only {@link #PROPAGATION_REQUIRED},
 * {@link #PROPAGATION_REQUIRES_NEW} and {@link #PROPAGATION_NESTED} can cause
 * that, it usually doesn't make sense to specify those settings in other cases.
 * Furthermore, be aware that not all transaction managers will support those
 * advanced features and thus might throw corresponding exceptions when given
 * non-default values.
 *
 * <p>The {@link #isReadOnly() read-only flag} applies to any transaction context,
 * whether backed by an actual resource transaction or operating non-transactionally
 * at the resource level. In the latter case, the flag will only apply to managed
 * resources within the application, such as a Hibernate {@code Session}.
 *
 * @author Juergen Hoeller
 * @since 08.05.2003
 * @see PlatformTransactionManager#getTransaction(TransactionDefinition)
 * @see org.springframework.transaction.support.DefaultTransactionDefinition
 * @see org.springframework.transaction.interceptor.TransactionAttribute
 */
public interface TransactionDefinition {

   /**
    * Support a current transaction; create a new one if none exists.
    * Analogous to the EJB transaction attribute of the same name.
    * <p>This is typically the default setting of a transaction definition,
    * and typically defines a transaction synchronization scope.
    */
   int PROPAGATION_REQUIRED = 0;  //事务传播级别1:当前如果有事务,Spring就会使用该事务;否则会开始一个新事务;(这也是默认设置和定义)

   /**
    * Support a current transaction; execute non-transactionally if none exists.
    * Analogous to the EJB transaction attribute of the same name.
    * <p><b>NOTE:</b> For transaction managers with transaction synchronization,
    * {@code PROPAGATION_SUPPORTS} is slightly different from no transaction
    * at all, as it defines a transaction scope that synchronization might apply to.
    * As a consequence, the same resources (a JDBC {@code Connection}, a
    * Hibernate {@code Session}, etc) will be shared for the entire specified
    * scope. Note that the exact behavior depends on the actual synchronization
    * configuration of the transaction manager!
    * <p>In general, use {@code PROPAGATION_SUPPORTS} with care! In particular, do
    * not rely on {@code PROPAGATION_REQUIRED} or {@code PROPAGATION_REQUIRES_NEW}
    * <i>within</i> a {@code PROPAGATION_SUPPORTS} scope (which may lead to
    * synchronization conflicts at runtime). If such nesting is unavoidable, make sure
    * to configure your transaction manager appropriately (typically switching to
    * "synchronization on actual transaction").
    * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
    * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#SYNCHRONIZATION_ON_ACTUAL_TRANSACTION
    */
   int PROPAGATION_SUPPORTS = 1;//事务传播级别2:如果有事务,Spring就会使用该事务;否则不会开始一个新事务

   /**
    * Support a current transaction; throw an exception if no current transaction
    * exists. Analogous to the EJB transaction attribute of the same name.
    * <p>Note that transaction synchronization within a {@code PROPAGATION_MANDATORY}
    * scope will always be driven by the surrounding transaction.
    */
   int PROPAGATION_MANDATORY = 2;  //事务传播级别3:当前如果有事务,Spring就会使用该事务;否则会因为没有事务而抛出异常



   /**
    * Create a new transaction, suspending the current transaction if one exists.
    * Analogous to the EJB transaction attribute of the same name.
    * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
    * on all transaction managers. This in particular applies to
    * {@link org.springframework.transaction.jta.JtaTransactionManager},
    * which requires the {@code javax.transaction.TransactionManager} to be
    * made available it to it (which is server-specific in standard Java EE).
    * <p>A {@code PROPAGATION_REQUIRES_NEW} scope always defines its own
    * transaction synchronizations. Existing synchronizations will be suspended
    * and resumed appropriately.
    * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
    */
   int PROPAGATION_REQUIRES_NEW = 3;//事务传播级别4:总是要开启一个新事务。如果当前已经有事务,则将已有事务挂起

   /**
    * Do not support a current transaction; rather always execute non-transactionally.
    * Analogous to the EJB transaction attribute of the same name.
    * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
    * on all transaction managers. This in particular applies to
    * {@link org.springframework.transaction.jta.JtaTransactionManager},
    * which requires the {@code javax.transaction.TransactionManager} to be
    * made available it to it (which is server-specific in standard Java EE).
    * <p>Note that transaction synchronization is <i>not</i> available within a
    * {@code PROPAGATION_NOT_SUPPORTED} scope. Existing synchronizations
    * will be suspended and resumed appropriately.
    * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
    */
   int PROPAGATION_NOT_SUPPORTED = 4;//事务传播级别5:代码总是在非事务环境下执行,如果当前有事务,则将已有事务挂起,再执行代码,之后恢复事务

   /**
    * Do not support a current transaction; throw an exception if a current transaction
    * exists. Analogous to the EJB transaction attribute of the same name.
    * <p>Note that transaction synchronization is <i>not</i> available within a
    * {@code PROPAGATION_NEVER} scope.
    */
   int PROPAGATION_NEVER = 5; //事务传播级别6:绝对不允许代码在事务中执行。如果当前运行环境有事务存在,则直接抛出异常,结束运行

   /**
    * Execute within a nested transaction if a current transaction exists,
    * behave like {@link #PROPAGATION_REQUIRED} else. There is no analogous
    * feature in EJB.
    * <p><b>NOTE:</b> Actual creation of a nested transaction will only work on
    * specific transaction managers. Out of the box, this only applies to the JDBC
    * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager}
    * when working on a JDBC 3.0 driver. Some JTA providers might support
    * nested transactions as well.
    * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
    */
   int PROPAGATION_NESTED = 6;//事务传播级别7:该级别支持嵌套事务执行。如果没有父事务存在,那么执行情况与PROPAGATION_REQUIRED一样;典型的应用是批量数据入库,开启父事务对一批数据入库,而对于每条入库的数据
   都有一个子事务对应,那么当所有的子事务成功,父事务提交,才算成功,否则,就都失败。


   /**
    * Use the default isolation level of the underlying datastore.
    * All other levels correspond to the JDBC isolation levels.
    * @see java.sql.Connection
    */
   int ISOLATION_DEFAULT = -1;
//事务隔离级别1:默认的隔离级别,同数据库一样的,如果不做特别设置,mysql默认的是可重复读,而oracle默认的是读提交

   /**
    * Indicates that dirty reads, non-repeatable reads and phantom reads
    * can occur.
    * <p>This level allows a row changed by one transaction to be read by another
    * transaction before any changes in that row have been committed (a "dirty read").
    * If any of the changes are rolled back, the second transaction will have
    * retrieved an invalid row.
    * @see java.sql.Connection#TRANSACTION_READ_UNCOMMITTED
    */
   int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
//事务隔离级别2:读未提交,即一个事务可以读取另外一个事务中未提交的数据,即脏读数据存在,性能最好,但是没啥用。
   /**
    * Indicates that dirty reads are prevented; non-repeatable reads and
    * phantom reads can occur.
    * <p>This level only prohibits a transaction from reading a row
    * with uncommitted changes in it.
    * @see java.sql.Connection#TRANSACTION_READ_COMMITTED
    */
   int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
//事务隔离级别3:读提交,即一个事务只能读取到另一个事务提交后的数据,oracle数据库默认隔离级别;存在不可重复读问题,即交叉事务出现,A事务两次读取数据可能会读到B事务提交的修改后的数据,即在同一个事务中读到了不同的数据,也叫不可重复读
/**
* Indicates that dirty reads and non-repeatable reads are prevented;    
* phantom reads can occur.    
* <p>This level prohibits a transaction from reading a row with uncommitted changes    
* in it, and it also prohibits the situation where one transaction reads a row,   
 * a second transaction alters the row, and the first transaction re-reads the row,    
* getting different values the second time (a "non-repeatable read").    
* @see java.sql.Connection#TRANSACTION_REPEATABLE_READ    */
   int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
//事务隔离级别4:可重复读,即一个事务只能读取到在次事务之前提交的数据,而之后提交不能读取到,不管对方的事务是否提交都读取不到,mysql默认的隔离级别。此隔离级别有可能会遇到幻读现象,但是mysql 基于innodb引擎实现的数据库已经通过多版本控制解决了此问题,所以可以不考虑了。
/**    
* Indicates that dirty reads, non-repeatable reads and phantom reads    
* are prevented.    
* <p>This level includes the prohibitions in {@link #ISOLATION_REPEATABLE_READ}   
 * and further prohibits the situation where one transaction reads all rows that    
* satisfy a {@code WHERE} condition, a second transaction inserts a row    
* that satisfies that {@code WHERE} condition, and the first transaction    
* re-reads for the same condition, retrieving the additional "phantom" row    
* in the second read.    * @see java.sql.Connection#TRANSACTION_SERIALIZABLE    
*/   
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;  
//事务隔离级别2:序列化读,每次都是全表锁,性能最差,安全性最高,一般场景不适用,也没有这个必要。
在开发的过程中,用事务最多的方式是通过注解@Transaction来完成的,虽然大多数的业务场景都可以在这一个注解下完成即可。
但是为了适应某些特别的场景比方说只读方法的优化等,通过对@Transaction来添加参数来完成我们想要的事务传播特性和隔离级别,以及是否只对某些异常类做回滚,是否只读方法等。
1)使用propagation 指定事务的传播行为,即当前的事务方法被另外一个事务方法调用时如何使用事务。
      默认取值为REQUIRED,即使用调用方法的事务
     REQUIRES_NEW:使用自己的事务,调用的事务方法的事务被挂起。
     
 2)使用isolation 指定事务的隔离级别,最常用的取值为READ_COMMITTED
 3)默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚,也可以通过对应的属性进行设置。通常情况下,默认值即可。
 4)使用readOnly 指定事务是否为只读。 表示这个事务只读取数据但不更新数据,这样可以帮助数据库引擎优化事务。若真的是一个只读取数据库值得方法,应设置readOnly=true
 5)使用timeOut 指定强制回滚之前事务可以占用的时间。
@Transactional(propagation = Propagation.MANDATORY,isolation = Isolation.READ_COMMITTED,noRollbackFor = {特定的异常类对象},readOnly = true,timeout = 3)
其中timeout的单位为秒。多个异常类对象,用逗号分隔即可。
 


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值