spring的事务传播行为种类

合集下载

spring事务传播行为

spring事务传播行为

//事务属性 PROPAGATION_REQUIRED
methodA(){
methodB();
}
//事务属性 PROPAGATION_MANDATORY
methodB(){
……
}
当单独调用methodB时,因为当前没有一个活动的事务,则会抛出异常throw new IllegalTransactionStateException(“Transaction propagation ‘mandatory’ but no existing transaction found”);当调用methodA时,methodB则加入到methodA的事务中,事务地执行。
} finally {
//释放资源
}
//释放资源
}
}
在这里,我把ts1称为外层事务,ts2称为内层事务。从上面的代码可以看出,ts2与ts1是两个独立的事务,互不相干。Ts2是否成功并不依赖于 ts1。如果methodA方法在调用methodB方法后的doSomeThingB方法失败了,而methodB方法所做的结果依然被提交。而除了 methodB之外的其它代码导致的结果却被回滚了。使用PROPAGATION_REQUIRES_NEW,需要使用 JtaTransactionManager作为事务管理器。
tm = getTransactionManager();
tm.begin();//开启一个新的事务
Transaction ts1 = tm.getTransaction();
doSomeThing();
tm.suspend();//挂起当前事务
con.rollback();

spring事务传播行为详解

spring事务传播行为详解

spring事务传播⾏为详解地址:⼀、什么是事务的传播?简单的理解就是多个事务⽅法相互调⽤时,事务如何在这些⽅法间传播。

举个栗⼦,⽅法A是⼀个事务的⽅法,⽅法A执⾏过程中调⽤了⽅法B,那么⽅法B有⽆事务以及⽅法B对事务的要求不同都会对⽅法A的事务具体执⾏造成影响,同时⽅法A的事务对⽅法B的事务执⾏也有影响,这种影响具体是什么就由两个⽅法所定义的事务传播类型所决定。

⼆、Spring事务传播类型枚举Propagation介绍在Spring中对于事务的传播⾏为定义了七种类型分别是:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。

在Spring源码中这七种类型被定义为了枚举。

源码在org.springframework.transaction.annotation包下的Propagation,源码中注释很多,对传播⾏为的七种类型的不同含义都有解释,后⽂中锤⼦我也会给⼤家分析,我在这⾥就不贴所有的源码,只把这个类上的注解贴⼀下,翻译⼀下就是:表⽰与TransactionDefinition接⼝相对应的⽤于@Transactional注解的事务传播⾏为的枚举。

也就是说枚举类Propagation是为了结合@Transactional注解使⽤⽽设计的,这个枚举⾥⾯定义的事务传播⾏为类型与TransactionDefinition 中定义的事务传播⾏为类型是对应的,所以在使⽤@Transactional注解时我们就要使⽤Propagation枚举类来指定传播⾏为类型,⽽不直接使⽤TransactionDefinition接⼝⾥定义的属性。

在TransactionDefinition接⼝中定义了Spring事务的⼀些属性,不仅包括事务传播特性类型,还包括了事务的隔离级别类型(事务的隔离级别后⾯⽂章会详细讲解),更多详细信息,⼤家可以打开源码⾃⼰翻译⼀下⾥⾯的注释package org.springframework.transaction.annotation;import org.springframework.transaction.TransactionDefinition;/*** Enumeration that represents transaction propagation behaviors for use* with the {@link Transactional} annotation, corresponding to the* {@link TransactionDefinition} interface.** @author Colin Sampaleanu* @author Juergen Hoeller* @since 1.2*/public enum Propagation {...}三、七种事务传播⾏为详解与⽰例在介绍七种事务传播⾏为前,我们先设计⼀个场景,帮助⼤家理解,场景描述如下现有两个⽅法A和B,⽅法A执⾏会在数据库ATable插⼊⼀条数据,⽅法B执⾏会在数据库BTable插⼊⼀条数据,伪代码如下://将传⼊参数a存⼊ATablepubilc void A(a){insertIntoATable(a);}//将传⼊参数b存⼊BTablepublic void B(b){insertIntoBTable(b);}接下来,我们看看在如下场景下,没有事务,情况会怎样public void testMain(){A(a1); //调⽤A⼊参a1testB(); //调⽤testB}public void testB(){B(b1); //调⽤B⼊参b1throw Exception; //发⽣异常抛出B(b2); //调⽤B⼊参b2}在这⾥要做⼀个重要提⽰:Spring中事务的默认实现使⽤的是AOP,也就是代理的⽅式,如果⼤家在使⽤代码测试时,同⼀个Service类中的⽅法相互调⽤需要使⽤注⼊的对象来调⽤,不要直接使⽤this.⽅法名来调⽤,this.⽅法名调⽤是对象内部⽅法调⽤,不会通过Spring代理,也就是事务不会起作⽤以上伪代码描述的⼀个场景,⽅法testMain和testB都没有事务,执⾏testMain⽅法,那么结果会怎么样呢?相信⼤家都知道了,就是a1数据成功存⼊ATable表,b1数据成功存⼊BTable表,⽽在抛出异常后b2数据存储就不会执⾏,也就是b2数据不会存⼊数据库,这就是没有事务的场景。

spring的事务传播级别及场景

spring的事务传播级别及场景

spring的事务传播级别及场景
1 PROPAGATION_REQUIRED :默认事务类型,如果没有,就新建⼀个事务;如果有,就加⼊当前事务。

适合绝⼤多数情况。

[关键点:是同⼀个事务]
场景:
不同的类,class1,class2
class1.fun1--->class2.fun2: fun1调⽤fun2 ,⽆论在fun1还是fun2⾥发⽣unchecked异常[不论是否catch处理异常],都会触发整个⽅法的回滚.
2 PROPAGATION_REQUIRES_NEW:如果没有,就新建⼀个事务;如果有,就将当前事务挂起.[关键点:2个事务是单独的,没有依赖关系]场景:
class1.fun1--->class2.fun2: fun1调⽤fun2 ,
如果fun2抛出异常且被catch处理,则fun2回滚,fun1不回滚.
如果fun2抛出异常且没被catch处理,则fun2,fun1都回滚.
如果fun1抛出异常,则fun1回滚,fun2不回滚.
3 PROPAGATION_NESTED:如果没有,就新建⼀个事务;如果有,就在当前事务中嵌套其他事务。

[关键点:2个事务是依赖关系,fun2依赖fun1]
场景:
class1.fun1--->class2.fun2: fun1调⽤fun2,
如果fun2抛出异常且在fun1⾥catch处理了,则fun2回滚,fun1不回滚, 如果没有catch,则fun1也回滚.
如果fun1抛出异常,则fun1和fun2都回滚.
特别注意: 当Spring的事务在同⼀个类时,它的⾃我调⽤时事务将失效.。

spring trascation

spring trascation

1Spring事务传播行为所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。

Spring支持7种事务传播行为PROPAGATION_REQUIRED(加入已有事务)如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。

这是最常见也是默认的方式。

PROPAGATION_SUPPORTS(跟随环境)支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY(需要事务)使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW(独立事务)新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED(非事务方式)以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER(排除事务)以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED(嵌套事务)如果当前存在事务,则在嵌套事务内执行。

如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

Spring默认的事务传播行为是PROPAGATION_REQUIRED,它适合于绝大多数的情况。

假设ServiveX#methodX()都工作在事务环境下(即都被Spring事务增强了),假设程序中存在如下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这3个服务类的3个方法通过Spring的事务传播机制都工作在同一个事务中。

如果在一个ServiceA和a()方法中启动一个线程,在这个新创建的线程中执行ServiceB的事务方法b()。

在相同线程中进行相互嵌套调用的事务方法工作于相同的事务中。

如果这些相互嵌套调用的方法工作在不同的线程中,不同线程下的事务方法工作在独立的事务中。

事务属性的7种传播行为

事务属性的7种传播行为

事务属性的7种传播⾏为事务属性的7种传播⾏为编程式事务和声明式事务编程式事务管理使⽤TransactionTemplate或者直接使⽤底层的PlatformTransactionManager。

对于编程式事务管理,Spring推荐使⽤TransactionTemplate。

(参考四)/*** 数据源加⼊事务管理* @param masterDataSource* @return*/@Bean(name = "transactionManager")@Primarypublic DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("masterDataSource") DataSource masterDataSource){final DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(masterDataSource);return dataSourceTransactionManager;}/*** 事务管理加⼊事务模板* @param transactionManager* @return*/@Bean(name = "transactionTemplate")@Primarypublic TransactionTemplate masteerTransactionTemplate(@Qualifier("transactionManager") DataSourceTransactionManager transactionManager){final TransactionTemplate transactionTemplate = new TransactionTemplate();transactionTemplate.setTransactionManager(transactionManager);transactionTemplate.setIsolationLevelName("ISOLATION_DEFAULT");// 事物的传播属性transactionTemplate.setPropagationBehaviorName("PROPAGATION_REQUIRED");return transactionTemplate;}声明式事务管理建⽴在AOP之上的。

事务的传播行为

事务的传播行为

事务的传播⾏为
【简介】
当事务⽅法被另⼀个事务⽅法调⽤时,必须指定事务应该如何传播。

例如:⽅法可能继续在现有事务中运⾏,也可能开启⼀个新事务,并在⾃⼰的事务中运⾏。

事务的传播⾏为可以由传播属性指定。

Spring定义了7种类传播⾏为。

事务传播属性可以在@Transactional注解的propagation属性中定义。

【测试】
1) . 说明
①REQUIRED传播⾏为
当bookService的purchase()⽅法被另⼀个事务⽅法checkout()调⽤时,它默认会在现有的事务内运⾏。

这个默认的传播⾏为就
是REQUIRED。

因此在checkout()⽅法的开始和终⽌边界内只有⼀个事务。

这个事务只在checkout()⽅法结束的时候被提交,结果⽤户⼀本书都买不了。

②. REQUIRES_NEW传播⾏为
表⽰该⽅法必须启动⼀个新事务,并在⾃⼰的事务内运⾏。

如果有事务在运⾏,就应该先挂起它。

补充】】
在Spring 2.x事务通知中,可以像下⾯这样在<tx:method>元素中设定传播事务属性。

Spring中事务传播行为

Spring中事务传播行为

Spring中事务传播⾏为1. Spring中七种事务传播⾏为PROPAGATION(蔓延、传播、传输)事务传播⾏为类型说明PROPAGATION_REQUIRED如果当前没有事务,就新建⼀个事务,如果已经存在⼀个事务中,加⼊到这个事务中。

这是默认的事务传播⾏为PROPAGATION_SUPPORTS⽀持当前事务,如果当前没有事务,就以⾮事务⽅式执⾏。

PROPAGATION_MANDATORY使⽤当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。

(⼀个新的事务将启动,⽽且如果有⼀个现有的事务在运⾏的话,则这个⽅法将在运⾏期被挂起,直到新的事务提交或者回滚才恢复执⾏。

)PROPAGATION_NOT_SUPPORTED以⾮事务⽅式执⾏操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER以⾮事务⽅式执⾏,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执⾏。

如果当前没有事务,则执⾏与PROPAGATION_REQUIRED类似的操作。

(外层事务抛出异常回滚,那么内层事务必须回滚,反之内层事务并不影响外层事务)2. Spring中七种事务定义Spring在TransactionDefinition接⼝中规定了7种类型的事务传播⾏为。

事务传播⾏为是Spring框架独有的事务增强特性。

这是Spring为我们提供的强⼤的⼯具箱,使⽤事务传播⾏可以为我们的开发⼯作提供许多便利。

TransactionDefinition接⼝定义public interface TransactionDefinition {int PROPAGATION_REQUIRED = 0;int PROPAGATION_SUPPORTS = 1;int PROPAGATION_MANDATORY = 2;int PROPAGATION_REQUIRES_NEW = 3;int PROPAGATION_NOT_SUPPORTED = 4;int PROPAGATION_NEVER = 5;int PROPAGATION_NESTED = 6;int ISOLATION_DEFAULT = -1;int ISOLATION_READ_UNCOMMITTED = 1;int ISOLATION_READ_COMMITTED = 2;int ISOLATION_REPEATABLE_READ = 4;int ISOLATION_SERIALIZABLE = 8;int TIMEOUT_DEFAULT = -1;int getPropagationBehavior();int getIsolationLevel();int getTimeout();boolean isReadOnly();@NullableString getName();}Transactional注解的定义public @interface Transactional {@AliasFor("transactionManager")String value() default "";@AliasFor("value")String transactionManager() default "";Propagation propagation() default Propagation.REQUIRED;Isolation isolation() default Isolation.DEFAULT;int timeout() default -1;boolean readOnly() default false;Class<? extends Throwable>[] rollbackFor() default {};String[] rollbackForClassName() default {};Class<? extends Throwable>[] noRollbackFor() default {};String[] noRollbackForClassName() default {};}事务传播⾏为⽤来描述由某⼀个事务传播⾏为修饰的⽅法被嵌套进另⼀个⽅法的时事务如何传播。

spring实现事务配置的方式,事务7大传播属性的区别

spring实现事务配置的方式,事务7大传播属性的区别

spring实现事务配置的⽅式,事务7⼤传播属性的区别⼀、注解式事务1、注解式事务在平时的开发中使⽤的挺多,⼯作的两个公司中看到很多项⽬使⽤了这种⽅式,下⾯看看具体的配置demo。

2、事务配置实例(1)、spring+mybatis 事务配置<!-- 定义事务管理器 --><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!--使⽤注释事务 --><tx:annotation-driven transaction-manager="transactionManager" />(2)、spring+hibernate 事务配置<!-- 事务管理器配置,单数据源事务 --><bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><!-- 使⽤annotation定义事务 --><tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />看到上⾯的这两段配置⽂件是不是很熟悉,对的这就是我们平时看到的事务的配置,在spring的配置中配置数据源即dataSource、事务管理器,事务管理器使⽤不同的orm框架事务管理器类就不同,⽐如这⾥使⽤的是mybatis 所以是org.springframework.jdbc.datasource.DataSourceTransactionManager如果使⽤hibernate 则事务管理器类为org.springframework.orm.hibernate3.HibernateTransactionManager这是使⽤注解⽅式时要配置的,代码中的具体的注解以及事务的传播性、隔离级别⼀般在service 层中配置下⾯看看3、@Transactional(1)、这⾥说明⼀下,有的把这个注解放在类名称上⾯了,这样你配置的这个@Transactional 对这个类中的所有public⽅法都起作⽤(2)、@Transactional ⽅法⽅法名上,只对这个⽅法有作⽤,同样必须是public的⽅法⽐如这⾥就对这个⽅法定义了⼀个事务同时设置了很多属性:@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,timeout=1,isolation=Isolation.DEFAULT)public void saveUser(Map<String, String> map) throws Exception {System.out.println("⽅法开始");for (int i = 0; i < 500000; i++) {System.out.println("*");}System.out.println("进⼊保存");userDao.saveUser(map);System.out.println("退出保存");}4、事物配置中有哪些属性可以配置(1)、事务的传播性:@Transactional(propagation=Propagation.REQUIRED)如果有事务, 那么加⼊事务, 没有的话新建⼀个(默认情况下)(2)、事务的超时性:@Transactional(timeout=30) //默认是30秒注意这⾥说的是事务的超时性⽽不是Connection的超时性,这两个是有区别的(3)、事务的隔离级别:@Transactional(isolation = Isolation.READ_UNCOMMITTED) ,未提交读,就是⼀个事务可以读取另⼀个未提交事务的数据。

transaction propagation用法

transaction propagation用法

在Spring框架中,事务传播行为(Transaction Propagation)定义了当一个事务方法被另一个事务方法调用时,应如何处理事务。

以下是Spring框架中事务传播行为的几种类型:
PROPAGATION_REQUIRED:如果当前存在事务,则支持当前事务;如果没有事务,则新建一个事务。

这是最常见的选择。

PROPAGATION_SUPPORTS:如果当前存在事务,则支持当前事务;如果没有事务,则以非事务方式运行。

PROPAGATION_MANDATORY:如果当前存在事务,则支持当前事务;如果没有事务,则抛出异常。

PROPAGATION_REQUIRES_NEW:始终新建一个事务。

如果当前存在事务,则挂起当前事务。

PROPAGATION_NOT_SUPPORTED:始终非事务地执行,并挂起任何存在的事务。

PROPAGATION_NEVER:始终非事务地执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED:如果当前存在事务,则嵌套事务执行;如果没有当前事务,则按
TransactionDefinition.PROPAGATION_REQUIRED属性执行。

这些传播行为可以根据你的具体需求来选择使用。

例如,如果你希望一个方法在另一个事务方法被调用时总是开始新的事务,那么你
可以选择PROPAGATION_REQUIRES_NEW。

如果你希望一个方法在另一个事务方法被调用时使用现有的事务(如果没有现有事务,则以非事务方式运行),那么你可以选择PROPAGATION_SUPPORTS。

「聊一聊Spring」Spring的事务传播行为

「聊一聊Spring」Spring的事务传播行为

「聊⼀聊Spring 」Spring 的事务传播⾏为Spring中的事务传播⾏为事务管理并⾮ Spring ⾸创,Spring 也借鉴了很多其他的框架,然后加以统⼀。

在 Spring 中,我们经常使⽤声明式事务,在⽅法或类上添加 Spring 的 @Transtional 注解,在这个注解中我们可以指定事务传播⾏为,这个注解也参考了 EJB 的javax.ejb.TransactionAttribute 以及 JTA 的 javax.transaction.Transactional,这⾥先通过对⽐认识⼀下这三者的异同。

从上⾯的表格中可以看到,在 Spring 的 @Transactional 中都可以找到 EJB、JTA 注解中相应的参数。

事实上,Spring 也对 EJB 的 @TransactionAttribute 注解及 JTA 的@Transactional 加以了⽀持,在 Spring 中这三个注解都可以使⽤。

现在将重点转向事务传播⾏为,上⾯的三个注解都有事务传播⾏为,那么这三者的事务传播⾏为⼜有何异同呢?有没有发现⼀些问题?Spring 中的事务定义与 EJB、JTA 基本⼀致,它们名称不仅相同,事实上语义和实现也相似,⽽且 Spring 还增加了⼀个 NESTED 类型的事务传播⾏为。

事务传播⾏为主要是控制新⽅法执⾏时是否使⽤事务,如何处理线程中以存在的事务。

下⾯是对 Spring 中的这7中事务传播⾏为的描述:REQUIRED :默认的事务传播⾏为;需要事务:存在事务则使⽤已存在事务,否则创建新的事务;SUPPORTS :⽀持已存在事务:存在事务则使⽤已存在事务,否则以⾮事务⽅式运⾏;MANDATORY :强制使⽤事务:存在事务则使⽤已存在事务,否则抛出异常;REQUIRES_NEW :需要新事务:存在事务则挂起已存在事务,否则创建新事务;NOT_SUPPORTED :不⽀持事务:存在事务则挂起已存在事务,否则以⾮事务⽅式运⾏;NEVER :从不使⽤事务:存在事务则抛出异常,否则以⾮事务⽅式运⾏;NESTED :嵌套事务:存在事务则使创建保存点使⽤嵌套的事务,否则创建新的事务。

Spring事务的传播机制

Spring事务的传播机制

Spring事务的传播机制Spring事务的传播机制是指在多个事务方法相互调用的情况下,事务的传播规则和行为。

Spring框架提供了七种事务传播行为,分别为REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。

1.REQUIRED(默认):如果当前存在事务,则加入该事务,如果不存在事务,则创建一个新事务。

该传播行为是最常用的一种,适用于大多数业务场景。

例如,A方法调用B方法,B方法中使用REQUIRED传播行为,则B方法会加入A方法的事务中。

2.SUPPORTS:如果当前存在事务,则加入该事务,如果不存在事务,则以非事务的方式执行。

该传播行为适用于不需要强制事务的情况。

例如,A方法调用B方法,B方法中使用SUPPORTS传播行为,则B方法会根据当前是否存在事务来决定是否加入。

3.MANDATORY:如果当前存在事务,则加入该事务,如果不存在事务,则抛出异常。

该传播行为适用于必须在事务中执行的情况。

例如,A方法调用B方法,B方法中使用MANDATORY传播行为,则B方法会检查当前是否存在事务,如果不存在则抛出异常。

4.REQUIRES_NEW:无论当前是否存在事务,都创建一个新事务,并在新事务中执行。

该传播行为适用于需要独立事务执行的情况。

例如,A方法调用B方法,B方法中使用REQUIRES_NEW传播行为,则B方法会创建一个新事务并在其中执行。

5.NOT_SUPPORTED:以非事务的方式执行方法,如果当前存在事务,则将事务挂起。

该传播行为适用于不需要事务的情况。

例如,A方法调用B方法,B方法中使用NOT_SUPPORTED传播行为,则B方法会以非事务的方式执行。

6.NEVER:以非事务的方式执行方法,如果当前存在事务,则抛出异常。

该传播行为适用于必须在非事务中执行的情况。

例如,A方法调用B方法,B方法中使用NEVER传播行为,则B方法会检查当前是否存在事务,如果存在则抛出异常。

Spring事务传播机制

Spring事务传播机制

Spring事务传播机制 spring的管理的事务可以分为如下2类:逻辑事务:在spring中定义的事务通常指逻辑事务,提供⽐物理事务更抽象,⽅便的事务配置管理,但也基于物理事务物理事务:特定于数据库的事务 spring中⽀持⼀下2中事务声明⽅式编程式事务:当系统需要明确的,细粒度的控制各个事务的边界,应选择编程式事务声明式事务:当系统对于事务的控制粒度较粗时,应该选择申明式事 ⽆论你选择上述何种事务⽅式去实现事务控制,spring都提供基于门⾯设计模式的事务管理器供选择,如下是spring事务中⽀持的事务管理器UML结构图如下1.各种事务管理器的定义如下JdbcTransactionManager定义如下<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource"ref="dataSource"/></bean>View Codehibernate事务管理器配置如下<bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory"/></bean>View Code hibernate的事务管理器会注⼊session会话⼯⼚,然后将事务处理委托给当前的transaction对象,事务提交时,调⽤commit()⽅法,回滚时调⽤rollback()⽅法.其余事务管理器可参见spring in action中说明。

Spring声明式事务@Transactional详解,事务隔离级别和传播行为

Spring声明式事务@Transactional详解,事务隔离级别和传播行为

Spring声明式事务@Transactional详解,事务隔离级别和传播⾏为@Transactional注解⽀持9个属性的设置,这⾥只讲解其中使⽤较多的三个属性:readOnly、propagation、isolation。

其中propagation属性⽤来枚举事务的传播⾏为,isolation⽤来设置事务隔离级别,readOnly进⾏读写事务控制。

@Service@Transactional(readOnly = true)public class AppTradeRec2Service extends BaseService {@Autowiredprivate AppTradeRecDao appTradeRecDao;@Autowiredprivate ConsInfoDao consInfoDao;@Transactional(readOnly = false)public void payCharge(TradeRec tradeRec) {User usr = UserUtils.getUser();ConsInfo cons = consInfoDao.getByUser(usr.getId());//修改交易记录tradeRec.setPayBefore(cons.getAccountAmt());tradeRec.setPayAfter(cons.getAccountAmt() - tradeRec.getRcvAmt());tradeRec.setIsPay("99");appTradeRecDao.save(tradeRec);//修改账户余额cons.setAccountAmt(cons.getAccountAmt() - tradeRec.getRcvAmt());consInfoDao.save(cons);}}⼀、readOnly读写事务控制readOnly=true表明所注解的⽅法或类只是读取数据。

spring传播事务和隔离级别

spring传播事务和隔离级别

Spring事务的传播行为和隔离级别7个传播行为,4个隔离级别,Spring事务的传播行为和隔离级别[transaction behavior and isolated level]2007-08-01 16:33事务的传播行为和隔离级别[transaction behavior and isolated level]Spring中事务的定义:一、Propagation :key属性确定代理应该给哪个方法增加事务行为。

这样的属性最重要的部份是传播行为。

有以下选项可供使用:PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。

这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

很多人看到事务的传播行为属性都不甚了解,我昨晚看了j2ee without ejb的时候,看到这里也不了解,甚至重新翻起数据库系统的教材书,但是也没有找到对这个的分析。

今天搜索,找到一篇极好的分析文章,虽然这篇文章是重点分析PROPAGATION_REQUIRED 和PROPAGATION_REQUIRED_NESTED的解惑spring 嵌套事务/*** @author 王政* @date 2006-11-24* @note 转载自/topic/35907?page=1*/ ********TransactionDefinition 接口定义*******************/*** Support a current transaction, create a new one if none exists.* Analogous to EJB transaction attribute of the same name.* <p>This is typically the default setting of a transaction definition.*/int PROPAGATION_REQUIRED = 0;/*** Support a current transaction, execute non-transactionally if none exists.* Analogous to EJB transaction attribute of the same name.* <p>Note: For transaction managers with transaction synchronization,* PROPAGATION_SUPPORTS is slightly different from no transaction at all,* as it defines a transaction scopp 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.* @seeorg.springframework.transaction.support.AbstractPlatformTransactionManager#setTransa ctionSynchronization*/int PROPAGATION_SUPPORTS = 1;/*** Support a current transaction, throw an exception if none exists.* Analogous to EJB transaction attribute of the same name.*/int PROPAGATION_MANDATORY = 2;/*** Create a new transaction, 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</code> to be * made available it to it (which is server-specific in standard J2EE).* @seeorg.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */int PROPAGATION_REQUIRES_NEW = 3;/*** 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</code> to be * made available it to it (which is server-specific in standard J2EE).* @seeorg.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */int PROPAGATION_NOT_SUPPORTED = 4;/*** Execute non-transactionally, throw an exception if a transaction exists.* Analogous to EJB transaction attribute of the same name.*/int PROPAGATION_NEVER = 5;/*** Execute within a nested transaction if a current transaction exists,* behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB.* <p>Note: Actual creation of a nested transaction will only work on specific* transaction managers. Out of the box, this only applies to the JDBC* 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;*************************************************************************在这篇文章里,他用两个嵌套的例子辅助分析,我这里直接引用了。

Spring:Spring事务的4种特性、5种隔离级别、7种传播特性

Spring:Spring事务的4种特性、5种隔离级别、7种传播特性

Spring:Spring事务的4种特性、5种隔离级别、7种传播特性此⽂章只作笔记记录,不作为讲解⽂章1. 事务的特性(4种)原⼦性(atomicity):强调事务的不可分割.⼀致性(consistency): 事务的执⾏的前后数据的完整性保持⼀致.隔离性(isolation): 事务执⾏的过程中, 不受其他事务的⼲扰, 即并发执⾏的事物之间互不⼲扰持久性(durability) : 事务⼀旦结束, 数据就持久到数据库2. 事务诱发的问题2.1 脏读事务A读到了事务B的已操作但未提交的数据.2.2 不可重复读事务A有多次查询,第⼀次读取数据后继续运⾏,第⼆次读到了事务B已经提交的 update 的数据导致事务A 内的多次查询结果不⼀致.2.3 幻读事务A有多次查询,第⼀次读取数据后继续运⾏,第⼆次读到了事务B已经提交的 insert ( delete )的数据导致事务A 内的多次查询结果不⼀致.2.4 事务丢失( 回滚丢失 )事务A运⾏增删改操作后( 还未提交 ),事务B也运⾏增删改操作并提交,事务A继续运⾏后报错进⾏事务回滚时,此时就会把事务B的操作清除掉。

2.5 事务丢失( 提交丢失 )事务A与事务B同时对⼀组数据运⾏增删改操作,事务B先⼀步提交事务,事务A继续运⾏后也提交事务,此时就会把事务B的操作清除掉。

3. 数据库的事务隔离级别(4种)部分数据库的默认事务隔离级别为已提交读;例:SQL Server、OracleMysql的默认事务隔离级别为:可重复读4. 事务的隔离级别(5种)4.1 ISOLATION_DEFAULT 使⽤数据库默认的隔离级别4.2 ISOLATION_READ_UNCOMMITTED 事务最低的隔离级别 ( 可能会导致脏读,不可重复读,幻读 )4.3 ISOLATION_READ_COMMITTED 保证⼀个事务修改的数据提交后才能被另外⼀个事务读取 ( 可能会导致不可重复读,幻读 )4.4 ISOLATION_REPEATABLE_READ 保证⼀个事务修改的数据提交后才能被另外⼀个事务读取 ( 可能会导致幻读 ) 保证⼀个事务读取数据后,另外⼀个事务才能修改 ( 可能会导致幻读 )4.5 ISOLATION_SERIALIZABLE 这是花费最⾼代价但是最可靠的事务隔离级别。

Spring事务传播机制

Spring事务传播机制

Spring事务传播机制概述当我们调用一个基于Spring的Service接口办法(如UserServiceaUser())时,它将运行于Spring管理的事务环境中,Service接口办法可能会在内部调用其它的Service接口办法以共同完成一个完整的业务操作,因此就会产生服务接口办法嵌套调用的状况,Spring通过事务传扬行为控制当前的事务如何传扬到被嵌套调用的目标服务接口办法中。

事务传扬是Spring举行事务管理的重要概念,其重要性怎么强调都不为过。

但是事务传扬行为也是被误会最多的地方,在本文里,我们将具体分析不同事务传扬行为的表现形式,把握它们之间的区分。

事务传扬行为种类 Spring在TransactionDefinition接口中规定了7种类型的事务传扬行为,它们规定了事务办法和事务办法发生嵌套调用时事务如何举行传扬:表1事务传扬行为类型事务传扬行为类型解释 PROPAGATION_REQUIRED 假如当前没有事务,就新建一个事务,假如已经存在一个事务中,加入到这个事务中。

这是最频繁的挑选。

PROPAGATION_SUPPORTS 支持当前事务,假如当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY 用法当前的事务,假如当前没有事务,就抛出异样。

PROPAGATION_REQUIRES_NEW 新建事务,假如当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,假如当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER 以非事务方式执行,假如当前存在事务,则抛出异样。

PROPAGATION_NESTED 假如当前存在事务,则在嵌套事务内执行。

假如当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

当用法PROPAGATION_NESTED时,底层的数据源必需基于JDBC 3.0,并且实现者需要支持保存点事务机制。

Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别

Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别

Spring事务配置的五种⽅式和spring⾥⾯事务的传播属性和事务隔离级别前段时间对Spring的事务配置做了⽐较深⼊的研究,在此之间对Spring的事务配置虽说也配置过,但是⼀直没有⼀个清楚的认识。

通过这次的学习发觉Spring的事务配置只要把思路理清,还是⽐较好掌握的。

总结如下:Spring配置⽂件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,⽆论哪种配置⽅式,⼀般变化的只是代理机制这部分。

DataSource、TransactionManager这两部分只是会根据数据访问⽅式有所变化,⽐如使⽤Hibernate进⾏数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。

具体如下图:根据代理机制的不同,总结了五种Spring事务的配置⽅式,配置⽂件如下:第⼀种⽅式:每个Bean都有⼀个代理<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:aop="/schema/aop"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd/schema/context /schema/context/spring-context-2.5.xsd /schema/aop/schema/aop/spring-aop-2.5.xsd"><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><property name="configLocation" value="classpath:hibernate.cfg.xml" /><property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /></bean><!-- 定义事务管理器(声明式的事务) --><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><!-- 配置DAO --><bean id="userDaoTarget" class="erDaoImpl"><property name="sessionFactory" ref="sessionFactory" /></bean><bean id="userDao"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><!-- 配置事务管理器 --><property name="transactionManager" ref="transactionManager" /><property name="target" ref="userDaoTarget" /><property name="proxyInterfaces" value="com.bluesky.spring.dao.GeneratorDao" /><!-- 配置事务属性 --><property name="transactionAttributes"><props><prop key="*">PROPAGATION_REQUIRED</prop></props></property></bean></beans>第⼆种⽅式:所有Bean共享⼀个代理基类<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:aop="/schema/aop"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd/schema/context /schema/context/spring-context-2.5.xsd /schema/aop/schema/aop/spring-aop-2.5.xsd"><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /><property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /></bean><!-- 定义事务管理器(声明式的事务) --><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><bean id="transactionBase"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true" abstract="true"><!-- 配置事务管理器 --><property name="transactionManager" ref="transactionManager" /><!-- 配置事务属性 --><property name="transactionAttributes"><props><prop key="*">PROPAGATION_REQUIRED</prop></props></property></bean><!-- 配置DAO --><bean id="userDaoTarget" class="erDaoImpl"><property name="sessionFactory" ref="sessionFactory" /></bean><bean id="userDao" parent="transactionBase" ><property name="target" ref="userDaoTarget" /></bean></beans>第三种⽅式:使⽤拦截器<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:aop="/schema/aop"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd/schema/context /schema/context/spring-context-2.5.xsd /schema/aop/schema/aop/spring-aop-2.5.xsd"><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /><property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /></bean><!-- 定义事务管理器(声明式的事务) --><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><bean id="transactionInterceptor"class="org.springframework.transaction.interceptor.TransactionInterceptor"><property name="transactionManager" ref="transactionManager" /><!-- 配置事务属性 --><property name="transactionAttributes"><props><prop key="*">PROPAGATION_REQUIRED</prop></props></property></bean><bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"><property name="beanNames"><list><value>*Dao</value></list></property><property name="interceptorNames"><list><value>transactionInterceptor</value></list></property></bean><!-- 配置DAO --><bean id="userDao" class="erDaoImpl"><property name="sessionFactory" ref="sessionFactory" /></bean></beans>第四种⽅式:使⽤tx标签配置的拦截器<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:aop="/schema/aop"xmlns:tx="/schema/tx"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd/schema/context /schema/context/spring-context-2.5.xsd /schema/aop/schema/aop/spring-aop-2.5.xsd/schema/tx /schema/tx/spring-tx-2.5.xsd"><context:annotation-config /><context:component-scan base-package="com.bluesky" /><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /><property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /></bean><!-- 定义事务管理器(声明式的事务) --><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="*" propagation="REQUIRED" /></tx:attributes></tx:advice><aop:config><aop:pointcut id="interceptorPointCuts" expression="execution(* com.bluesky.spring.dao.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" /></aop:config></beans>第五种⽅式:全注解<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:aop="/schema/aop"xmlns:tx="/schema/tx"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd/schema/context /schema/context/spring-context-2.5.xsd /schema/aop/schema/aop/spring-aop-2.5.xsd/schema/tx /schema/tx/spring-tx-2.5.xsd"><context:annotation-config /><context:component-scan base-package="com.bluesky" /><tx:annotation-driven transaction-manager="transactionManager"/><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /><property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /></bean><!-- 定义事务管理器(声明式的事务) --><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean></beans>此时在DAO上需加上@Transactional注解,如下:package com.bluesky.spring.dao;import java.util.List;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import ponent;import er;@Transactional@Component("userDao")public class UserDaoImpl extends HibernateDaoSupport implements UserDao {public List<User> listUsers() {return this.getSession().createQuery("from User").list();}}事务隔离级别spring⾥⾯事务的传播属性和事务隔离级别。

Spring七种事务传播行为与五种事务隔离级别

Spring七种事务传播行为与五种事务隔离级别

Spring七种事务传播⾏为与五种事务隔离级别⼀、事务的传播⾏为:通过Propagation定义:<!-- 配置事务通知 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 以⽅法为单位,指定⽅法应⽤什么事务属性:isolation:隔离级别 propagation:传播⾏为 read-only:是否只读--><tx:method name="transfer" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/><!--上⾯的⽅式只适⽤单个⽅法,当我们业务有很多个⽅法都要操作事务时,则要配置很多个,可以使⽤下⾯的通配符配置⽅式--><tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>省略update.. detele.....</tx:attributes></tx:advice>readOnly:事务属性中的readOnly标志表⽰对应的事务应该被最优化为只读事务。

这是⼀个最优化提⽰。

在⼀些情况下,⼀些事务策略能够起到显著的最优化效果,例如在使⽤Object/Relational映射⼯具(如:或TopLink)时避免dirty checking(试图“刷新”)。

spring中事务的传播行为

spring中事务的传播行为

spring中事务的传播行为
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为。

事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为。

这是Spring为我们提供的强大的工具箱,使用事务传播行可以为我们的开发工作提供许多便利。

但是人们对他的误解也颇多,你一定也听过“service方法事务最好不要嵌套”的传言。

要想正确的使用工具首先需要了解工具。

本文对七种事务传播行为做详细介绍,内容主要代码示例的方式呈现。

至少是两个东西,才可以发生传播。

事务传播行为(propagation behavior)指的是当一个事务方法调用到另一个事务方法时,这个事务应该如何运行。

事务传播行为是spring框架独有的,不属于数据库。

例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。

spring事务传播机制和隔离级别

spring事务传播机制和隔离级别

Spring事务传播机制与隔离级别一、spring支持7种事务传播行为1、propagation_required(xml文件中为required)当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。

(如果被调用端发生异常,那么调用端和被调用端事务都将回滚)。

2、propagation_supports(xml文件中为supports)当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行。

3、propagation_mandatory(xml文件中为mandatory)表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常。

4、propagation_nested(xml文件中为nested)如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。

如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。

如果封装事务不存在,则同propagation_required的一样。

5、propagation_never(xml文件中为never)当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常。

6、propagation_requires_new(xml文件中为requires_new)当前方法必须运行在它自己的事务中。

一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。

7、propagation_not_supported(xml文件中为not_supported)方法不应该在一个事务中运行。

如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行。

二、spring中的事务隔离级别1、isolation_default使用数据库默认的事务隔离级别。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

事务传播行为种类
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,
它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
表1事务传播行为类型
事务传播行为类型说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已
经存在一个事务中,加入到这个事务中。

这是最常
见的选择。

PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事
务方式执行。

PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出
异常。

PROPAGATION_REQUIRES_ NEW
新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPO RTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛
出异常。

PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。


果当前没有事务,则执行与PROPAGATION_REQUIRED
类似的操作。

注:在SPRING2.0的API帮助文档的org.springframework.transaction包中的Interface TransactionDefinition中找到相应的解释。

相关文档
最新文档