spring事务隔离级别
spring事务配置
Spring事务配置的五种方法事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。
这样可以防止出现脏数据,防止数据库数据出现问题。
开发中为了避免这种情况一般都会进行事务管理。
在JDBC中是通过Connection对象进行事务管理的,默认是自动提交事务,可以手工将自动提交关闭,通过commit方法进行提交,rollback方法进行回滚,如果不提交,则数据不会真正的插入到数据库中。
Hibernate中是通过Transaction进行事务管理,处理方法与JDBC中类似。
Spring不会直接去管理事务,它提供了很多可供选择的事务管理器,将事务委托给JTA或某些特定的平台事务实现. Spring一般是使用TransactionMananger进行管理,可以通过Spring的注入来完成此功能。
针对Spring事务管理总结如下:要想用Spring的事务管理机制,就需要把数据库的连接交给Spring来管理,(JDBC,SESSION道理一样),如果使用Hibernate框架,要把Session交给Spring管理。
在整个Service方法调用中,虽然Sevice调用了多个Dao,但是整个过程中Session只有一个。
也就是说你对数据库的DML操作,都会先保存在这个Session中,包括update,insert,delete。
当发生异常(这个异常可以是数据库的,也可以是程序的),Spring会把这个Session中对应的DML操作回滚。
Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。
DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。
事务的四个特性、四种隔离级别和七种传播行为
事务的四个特性、四种隔离级别和七种传播⾏为⼀、事务的四个特性1.1、什么是事务事务是数据库操作的最⼩⼯作单元,是作为单个逻辑⼯作单元执⾏的⼀系列操作;这些操作作为⼀个整体⼀起向系统提交,要么都执⾏、要么都不执⾏;事务是⼀组不可再分割的操作集合(⼯作逻辑单元);1.2、事务的四个特性(ACID)1. 原⼦性(atomicity):操作⼀组指令,要么全部成功,要么不执⾏。
只要其中⼀个指令执⾏失败,所有的指令都执⾏失败,数据进⾏回滚,回到执⾏指令前的数据状态。
2. ⼀致性(consistency):事务的执⾏使数据从⼀个状态转换为另⼀个状态,但是对于整个数据的完整性保持稳定。
3. 隔离性(isolation):隔离性是当多个⽤户并发访问数据库时,⽐如操作同⼀张表时,数据库为每⼀个⽤户开启的事务,不能被其他事务的操作所⼲扰,多个并发事务之间要相互隔离。
即要达到这么⼀种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执⾏。
4. 持久性(durability):当事务正确完成后,它对于数据的改变是永久性的。
例如我们在使⽤JDBC操作数据库时,在提交事务⽅法后,提⽰⽤户事务操作完成,当我们程序执⾏完成直到看到提⽰后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执⾏完成,否则就会造成我们看到提⽰事务处理完毕,但是数据库因为故障⽽没有执⾏事务的重⼤错误。
⼆、事务的四种隔离级别2.1、事务的并发问题在看事务的隔离级别之前,先来来⼀下事务并发执⾏带来的问题:1、脏读脏读是指在⼀个事务处理过程中读取了其他未提交事务中的数据。
例如你银⾏卡⾥有1000块钱,你的妻⼦打算买双500块钱的鞋⼦,她付钱的时候你查看银⾏卡余额为500元。
这个时候,你妻⼦觉得太贵了不买了,撤销还没提交的操作,这个时候就发⽣了脏读。
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事务的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事务隔离级别一、Propagation (事务的传播属性)Propagation:key属性确定代理应该给哪个方法增加事务行为。
这样的属性最重要的部份是传播行为。
有以下选项可供使用:PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。
这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
1: PROPAGATION_REQUIRED加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候,ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA的事务内部,就不再起新的事务。
而假如ServiceA.methodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。
这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。
即使ServiceB.methodB的事务已经被提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB 也要回滚2: PROPAGATION_SUPPORTS如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行3: PROPAGATION_MANDATORY必须在一个事务中运行。
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支持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使用数据库默认的事务隔离级别。
Spring事务隔离级别
Spring事务隔离级别Isolation Level(Spring事务隔离等级):1、ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,用法数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应2、ISOLATION_SERIALIZABLE 这是花费最高代价但是最牢靠的事务隔离级别。
事务被处理为挨次执行。
除了防止脏读,不行重复读外,还避开了幻像读,最严格的Spring事务隔离级别,事务串行执行,资源消耗最大;3、ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不行重复读。
但是可能浮现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避开下面的状况产生(不行重复读),但是带来了更多的性能损失。
4、ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才干被另外一个事务读取。
另外一个事务不能读取该事务未提交的数据。
这种事务隔离级别可以避开脏读浮现,但是可能会浮现不行重复读和幻像读。
该级别适用于大多数系统。
5、ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不行重复读和幻像读我们首先说并发中可能发生的3中不讨人喜爱的事情:1: Dirty reads--读脏数据。
也就是说,比如事务A的未提交(还依旧缓存)的数据被事务B读走,假如事务A失败回滚,会导致事务B所读取的的数据是错误的。
2: non-repeatable reads--数据不行重复读。
比如事务A中两处读取数据-total-的值。
在第一读的时候,total是100,然后事务B就把total的数据改成200,事务A 再读一次,结果就发觉,total居然就变成200了,造成事务A数据混乱。
3: phantom reads--幻象读数据,这个和non-repeatable reads 相像,也是同一个事务中多次读不全都的问题。
Spring事务隔离级别简介及实例解析
Spring事务隔离级别简介及实例解析本⽂研究的主要是Spring事务隔离级别(solation level)介绍及例⼦,具体如下。
当两个事务对同⼀个数据库的记录进⾏操作时,那么,他们之间的影响是怎么样的呢?这就出现了事务隔离级别的概念。
数据库的隔离性与并发控制有很⼤关系。
数据库的隔离级别是数据库的事务特性ACID的⼀部分。
ACID,即原⼦性(atomicity)、⼀致性(consistency)、隔离性(isolation)和持久性(durability)。
Spring的事务隔离级别有四个:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE。
还有⼀个,是数据库默认的隔离级别DEFAULT,MySQL默认是REPEATABLE_READ。
下⾯来具体看看。
READ_UNCOMMITTED顾名思义,READ_UNCOMMITTED意思是,⼀个事务可以读取到另⼀个事务未提交的事务记录。
换句话说,a transaction can read the data that is still uncommitted by other transactions。
这是Spring事务最弱的隔离级别。
见下⾯的图,事务A开启,写⼊⼀条记录,这时候,事务B读⼊数据,读到了这条记录,但是,之后事务A回滚。
因此,事务B读到的数据不是有效的(the database is in an invalid state)。
这种情况称为脏读(dirty read)。
除了脏读的问题,READ_UNCOMMITTED还可能出现non-repeatable read(不可重复读)和phantom read(幻读)的问题。
READ_COMMITTEDREAD_COMMITTED隔离级别表明,⼀个事务只能读取到已经提交的记录,不能读取到未提交的记录。
换句话说,a transaction can only read the committed data, and it can't read the uncommitted data.因此,dirty read的情况不再发⽣,但可能会出现其他问题。
Spring5个事务隔离级别和7个事务传播行为
Spring5个事务隔离级别和7个事务传播行为Spring五个事务隔离级别和七个事务传播行为Spring在TransactionDefinition接口中定义这些属性在TransactionDfinition接口中定义了五个不同的事务隔离级别ISOLATION_DEFAULT这是一个PlatfromTransactionManger默认的隔离级别,使用数据库默认的事务隔离级别,另外四个与JDBC的隔离级别相对应ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据这种隔离级别会产生脏读,不可重复读和幻像读脏读:当事务读取还未提交的数据时,就会发生这种事件。
幻像读:如果允许读未提交的数据,那就会出现幻想读,我写了一条数据到表中,并没有提交数据。
这时你来查所有的数据,那就把这条没提交的数据查出来了,并使用这条数据作了一些计算,但接下来我回滚了这条数据,那么你刚才的读就是有问题的,计算结果也是不正确的ISOLATION_READ_COMMITTED保证一个事务修改的数据提交后才能被另一个事务读取。
另外一个事务不能读取该事务未提交的数据。
这种事务隔离可以避免脏读的出现,但是可能出现不可重复读和幻像读。
ISOLATION_REPEATABLE_READ这种事务隔离可以防止脏读,不可重复读。
但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
ISOLATION——SERIALIZABLE这是花费最高代价最可靠的事务隔离级别。
事务被处理为顺序执行。
除了防止脏读,不可重复读外,还避免了幻像读。
在TransactionDefinition接口中定义了七个事务的传播行为PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。
如果没有事务则开启一个新的事务。
PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。
spring事务的实现方式和原理以及隔离级别
spring事务的实现⽅式和原理以及隔离级别
在使⽤spring框架时,可以有两种使⽤事务的⽅式,⼀种时编程式事务,⼀种是申明式事务,@Transactional注解就是申明式的。
⾸先,事务这个概念式数据库层⾯的,Spring只是基于数据库中的事务进⾏了扩展,以及提供了⼀些能让程序员更加⽅便操作事务的⽅式。
⽐如我们可以通过在某个⽅法上增加@Transaction注解,就可以开启事务,这个⽅法中所有的sql都会在⼀个事务中执⾏,统⼀成功或者失败。
在⼀个⽅法上加了@Transaction注解后,spring会基于这个类⽣成⼀个代理对象,会将这个代理对象作为bean,当在使⽤这个代理对象的⽅法时,如果这个⽅法上存在@Transaction注解,那么代理逻辑会先把事务的⾃动提交设置为false,然后再去执⾏原本的逻辑代码,如果执⾏逻辑代码没有出现异常,那么代理逻辑中就会将事务进⾏提交,如果执⾏业务逻辑⽅法出现了异常,那么则会将事务进⾏回滚。
当然,针对哪些异常回滚事务是可以配置的,可以利⽤@Transaction注解中的rollbackFor属性进⾏配置,默认情况下会对RuntimeException和Error进⾏回滚。
Spring事务隔离级别就是数据库的隔离级别,外加⼀个默认级别
读未提交
读已提交
可重复读
可串⾏化
数据库的配置隔离级别是读已提交⽽spring配置的隔离级别是可重复读,请问这时候以哪⼀个隔离级别为准?
以spring配置的为准,如果spring设置的隔离级别数据库不⽀持,效果还是取决于数据库。
Spring事务隔离级别与传播机制详解,spring+mybatis+atomikos实现。。。
Spring事务隔离级别与传播机制详解,spring+mybatis+atomikos实现。
原创说明:本⽂为本⼈原创作品,绝⾮他处转载,转账请注明出处1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功。
其必须遵循四个原则(ACID)。
1. 原⼦性(Atomicity):即事务是不可分割的最⼩⼯作单元,事务内的操作要么全做,要么全不做;2. ⼀致性(Consistency):在事务执⾏前数据库的数据处于正确的状态,⽽事务执⾏完成后数据库的数据还是应该处于正确的状态,即数据完整性约束没有被破坏;如银⾏转帐,A转帐给B,必须保证A的钱⼀定转给B,⼀定不会出现A的钱转了但B没收到,否则数据库的数据就处于不⼀致(不正确)的状态。
3. 隔离性(Isolation):并发事务执⾏之间互不影响,在⼀个事务内部的操作对其他事务是不产⽣影响,这需要事务隔离级别来指定隔离性;4. 持久性(Durability):事务⼀旦执⾏成功,它对数据库的数据的改变必须是永久的,不会因⽐如遇到系统故障或断电造成数据不⼀致或丢失。
2.事务的类型1. 数据库分为本地事务跟全局事务本地事务:普通事务,独⽴⼀个数据库,能保证在该数据库上操作的ACID。
分布式事务:涉及两个或多个数据库源的事务,即跨越多台同类或异类数据库的事务(由每台数据库的本地事务组成的),分布式事务旨在保证这些本地事务的所有操作的ACID,使事务可以跨越多台数据库;2. Java事务类型分为JDBC事务跟JTA事务JDBC事务:即为上⾯说的数据库事务中的本地事务,通过connection对象控制管理。
JTA事务:JTA指Java事务API(Java Transaction API),是Java EE数据库事务规范, JTA只提供了事务管理接⼝,由应⽤程序服务器⼚商(如WebSphereApplication Server)提供实现,JTA事务⽐JDBC更强⼤,⽀持分布式事务。
SpringBoot事务隔离等级和传播行为
SpringBoot事务隔离等级和传播⾏为⼀、开启事物管理//import org.springframework.transaction.annotation.EnableTransactionManagement;@SpringBootApplication@EnableTransactionManagement //显⽰开启事物管理,springboot默认已经开启事物管理,可不⽤显⽰的注解public class Application extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(Application.class);}public static void main(String[] args) {SpringApplication.run(Application.class, args);}}⼆、配置事物在需要事物的类或⽅法上使⽤@Transactional(import org.springframework.transaction.annotation.Transactional)1、isolation 隔离级别(Springboot默认值为Isolation.DEFAULT)⽤法:@Transactional(isolation=Isolation.DEFAULT)public void test() {}枚举值(org.springframework.transaction.annotation):public enum Isolation {DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);}DEFAULT:默认值,表⽰使⽤底层数据库的默认隔离级别。
Spring事务隔离级别和传播机制
Spring事务隔离级别和传播机制引⾔什么是事务?在理解事务之前,我们要先了解事务的基本作⽤⽐如在⽣活中有这样⼀个场景————取钱,每个⼈应该都⼲过的事在ATM机上取钱,1.输⼊密码————2.输⼊⾦额————3.银⾏扣钱————4.ATM出钱以上⼏个步骤中,3和4就是必须是⼀个事务,因为它们之间,要么都完成,要么都不完成事务其实就是⽤来解决这种类似的问题想象⼀理,如果第3步成功了,第4步失败(报错)了,这将会导致⾮常严重的后果,对于普通⼈⽽⾔,钱被扣了,但ATM机没出钱,肯定会发飙的吧。
哈哈所以第3步和第4步,必须要全部被执⾏完成,这样才能保证最后数据的⼀致性。
对应到业务开发过程中,第3步和第4步,我们把它认为是⼀个执⾏单元,但在代码⾥⾯它是⼀条条的代码,所以必须要有⼀种机制能够保证它们要么全部执⾏成功,要么全部执⾏失败。
在企业级应⽤程序开发中,事务管理是必不可少的技术,⽤来确保数据的完整性和⼀致性。
Spring事务是建⽴在持久层的基础之上的,要理解Spring事务,就必须要先了解事务的相关特性事务特性1. 原⼦性(Atomicity)事务是⼀个原⼦操作,由⼀系列动作组成。
事务的原⼦性确保动作要么全部完成,要么完全不起作⽤。
2. ⼀致性(Consistency)⼀旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于⼀致的状态,⽽不会是部分完成部分失败。
在现实中的数据不应该被破坏。
3. 隔离性(Isolation)可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防⽌数据损坏。
4. 持久性(Durability)⼀旦事务完成,⽆论发⽣什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。
通常情况下,事务的结果被写到持久化存储器中。
Mysql事务实现1.获取连接2.关闭⾃动提交功能(SET AUTOCOMMIT = FALSE)3.开启事务4.业务SQL语句5.提交事务6.打开⾃动提交功能(SET AUTOCOMMIT = TRUE)7.关闭连接Mysql(InnoDB)实现源码Spring事务实现原理Spring⽀持编程式事务管理以及声明式事务管理两种⽅式。
spring事务配置方式以及事务的传播性、隔离级别
spring事务配置⽅式以及事务的传播性、隔离级别在前⾯的⽂章中总结了事务的5中配置⽅式,但是很多⽅式都不⽤⽽且当时的配置使⽤的所有参数都是默认的参数,这篇⽂章就看常⽤的两种事务配置⽅式并信息配置事务的传播性、隔离级别、以及超时等问题,废话不说下⾯就来看看!⼀、注解式事务1、注解式事务在平时的开发中使⽤的挺多,⼯作的两个公司中看到很多项⽬使⽤了这种⽅式,下⾯看看具体的配置demo。
2、事务配置实例(1)、spring+mybatis 事务配置[html]1. <!-- 定义事务管理器 -->2. <bean id="transactionManager"3. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">4. <property name="dataSource" ref="dataSource" />5. </bean>6. <!--使⽤注释事务 -->7. <tx:annotation-driven transaction-manager="transactionManager" />(2)、spring+ 事务配置[html]1. <!-- 事务管理器配置,单数据源事务 -->2. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">3. <property name="sessionFactory" ref="sessionFactory" />4. </bean>5.6. <!-- 使⽤annotation定义事务 -->7. <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />看到上⾯的这两段配置⽂件是不是很熟悉,对的这就是我们平时看到的事务的配置,在spring的配置中配置数据源即dataSource、事务管理器,事务管理器使⽤不同的orm框架事务管理器类就不同,⽐如这⾥使⽤的是mybatis 所以是[html]1. org.springframework.jdbc.datasource.DataSourceTransactionManager如果使⽤hibernate 则事务管理器类为[html]1. org.springframework.orm.hibernate3.HibernateTransactionManager这是使⽤注解⽅式时要配置的,代码中的具体的注解以及事务的传播性、隔离级别⼀般在service 层中配置下⾯看看3、@Transactional(1)、这⾥说明⼀下,有的把这个注解放在类名称上⾯了,这样你配置的这个@Transactional 对这个类中的所有public⽅法都起作⽤(2)、@Transactional ⽅法⽅法名上,只对这个⽅法有作⽤,同样必须是public的⽅法⽐如这⾥就对这个⽅法定义了⼀个事务同时设置了很多属性:[java]1. @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,timeout=1,isolation=Isolation.DEFAULT)2. public void saveUser(Map<String, String> map) throws Exception {3. System.out.println("⽅法开始");4. for (int i = 0; i < 500000; i++) {5. System.out.println("*");6. }7. System.out.println("进⼊保存");8. userDao.saveUser(map);9. System.out.println("退出保存");10. }4、事物配置中有哪些属性可以配置(1)、事务的传播性:@Transactional(propagation=Propagation.REQUIRED)如果有事务, 那么加⼊事务, 没有的话新建⼀个(默认情况下)(2)、事务的超时性:@Transactional(timeout=30) //默认是30秒注意这⾥说的是事务的超时性⽽不是Connection的超时性,这两个是有区别的(3)、事务的隔离级别:@Transactional(isolation = Isolation.READ_UNCOMMITTED)读取未提交数据(会出现脏读, 不可重复读) 基本不使⽤(4)、回滚:指定单⼀异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})该属性⽤于设置需要进⾏回滚的异常类数组,当⽅法中抛出指定异常数组中的异常时,则进⾏事务回滚。
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⾥⾯事务的传播属性和事务隔离级别。
defaulttransactiondefinition 设置隔离级别
defaulttransactiondefinition 设置隔离级别
在Spring框架中,可以使用DefaultTransactionDefinition类来设置事务的隔离级别。
DefaultTransactionDefinition类是TransactionDefinition接口的默认实现。
要设置隔离级别,可以使用DefaultTransactionDefinition类的setIsolationLevel()方法。
该方法接受一个int类型的参数,表示要设置的隔离级别。
常见的隔离级别包括:
•TransactionDefinition.ISOLATION_DEFAULT:使用默认的隔离级别•TransactionDefinition.ISOLATION_READ_UNCOMMITTED:读取未提交的数据•TransactionDefinition.ISOLATION_READ_COMMITTED:读取已提交的数据•TransactionDefinition.ISOLATION_REPEATABLE_READ:可重复读取的数据•TransactionDefinition.ISOLATION_SERIALIZABLE:可串行化的数据
以下是一个示例代码,演示如何设置事务的隔离级别:
通过调用setIsolationLevel()方法,可以将隔离级别设置为所需的值。
然后,可以将DefaultTransactionDefinition对象传递给事务管理器或事务模板,以在Spring 事务中使用该隔离级别。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
methodB();
doSomeThingB();
}
//事务属性 PROPAGATION_REQUIRES_NEW
methodB(){
……
}
当单独调用methodB时,相当于把methodb声明为REQUIRED。开启一个新的事务,事务地执行。
在TransactionDefinition接口中定义了七个事务传播行为。
1、PROPAGATION_REQUIRED
2、PROPAGATION_SUPPORTS
3、PROPAGATION_MANDATORY
4、PROPAGATION_REQUIRES_NEW
5、PROPAGATION_NOT_SUPPORTED
3、ISOLATION_READ_COMMITTED
4、ISOLATION_REPEATABLE_READ
5、ISOLATION_SERIALIZABLE
1、ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应
mit();
在事务1中,Mary 再次读取自己的工资时,工资变为了2000
代码
//con1
select salary from employee empId ="Mary";
在一个事务中前后两次读取的结果并不致,导致了不可重复读。
使用ISOLATION_REPEATABLE_READ可以避免这种情况发生。
5、ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
目前工资为1000的员工有10人。
事务1,读取所有工资为1000的员工。
代码
con1 = getConnection();
当调用methodA时,methodB则加入到methodA的事务中,事务地执行。
4、PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
代码
//事务属性 PROPAGATION_REQUIRED
methodA(){
Spring在TransactionDefinition接口中定义这些属性,以供PlatfromTransactionManager使用, PlatfromTransactionManager是spring事务管理的核心接口。
代码
TransactionDefinition
public interface TransactionDefinition {
int getPropagationBehavior();
int getIsolationLevel();
int getTimeout();
boolean isReadOnly();
}
getTimeout()方法,它返回事务必须在多少秒内完成。
isReadOnly(),事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的。
con1 = getConnection();
select salary from employee empId ="Mary";
在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.
代码
con2 = getConnection();
update employee set salary = 2000;
con.setAutoCommit(false);
update employee set salary = 8000 where empId ="Mary";
与此同时,Mary正在读取自己的工资
代码
Connection con2 = getConnection();
select salary from employee where empId ="Mary";
单独调用MethodA时,在MethodA内又会调用MethodB.
执行效果相当于
代码
main{
Connection con = null;
try{
con = getConnection();
methodA();
mit();
}
cathc(RuntimeException ex){
单独调用methodB方法
代码
main{
metodB();
}
相当于
代码
Main{
Connection con=null;
rry{
con = getConnection();
con.setAutoCommit(false);
//方法调用
methodB();
methodB();
……
}
//事务属性 PROPAGATION_REQUIRED
methodB{
……
}
使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
getPropagationBehavior()返回事务的传播行为,由是否有一个活动的事务来决定一个事务调用。
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Select * from employee where salary =1000;
共读取10条记录
这时另一个事务向employee表插入了一条员工记录,工资也为1000
代码
con2 = getConnection();
Insert into employee(empId,salary) values("Lili",1000);
mit();
事务1再次读取所有工资为1000的员工
代码
//con1
select * from employee where salary =1000;
共读取到了11条记录,这就产生了幻像读。
ISOLATION_SERIALIZABLE能避免这样的情况发生。但是这样也耗费了最大的资源。
mit();
Mary发现自己的工资变为了8000,欢天喜地!
而财务发现操作有误,而回滚了事务,Mary的工资又变为了1000
代码
//con1
con1.rollback();
像这样,Mary记取的工资数8000是一个脏数据。
3、ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
4、ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
在事务1中,Mary 读取了自己的工资为1000,操作并没有完成
代码
3、PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
代码
//事务属性 PROPAGATION_REQUIRED
methodA(){
methodB();
}
//事务属性 PROPAGATION_MANDATORY
Spring中的隔离级别和传播途径
Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要我们在与事务相关的方法中处理大量的try…catch…finally代码。
我们在使用Spring声明式事务时,有一个非常重要的概念就是事务属性。事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。我们在进行事务划分时,需要进行事务定义,也就是配置事务的属性。
tm.begin();//开启一个新的事务
methodB(){
……
}
当单独调用methodB时,因为当前没有一个活动的事务,则会抛出异常
throw new IllegalTransactionStateException("Transaction propagation 'mandatory' but no existing transaction found");