关于概念性的放在最下面,熟读几遍
在使用时候也没多关注,总是加个@Transactional
初识下
一般查询
@Transactional(propagation = Propagation.SUPPORTS)
增删改
@Transactional(propagation = Propagation.REQUIRED)
当然不能这么马虎
Spring中关于事务的传播
一个个测试,事务注解点进去看下,他其实
测试类
首先将表清空
第一次测试,不添加任何事务注解
程序在saveChildren()中会报错,导致的结果:因为没有添加事务注解 saveChild1()运行成功
但是saveChild2因为报错没有执行到
现在测试@Transactional
默认是@Transactional(propagation=Propagation.REQUIRED)
清空数据库
执行测试方法
结果就是因报错,事务回滚,一条数据也没有插入
再来测试另外一个
结果是
原因:saveParent()方法没有报错,且没有事务,因此插入成功
而saveChildren()方法中有事务且报错,事务回滚,
上面测试的是REQUIRED
在Spring事务传播中
REQUIRED:使用当前的事务,如果当前没有事务,则自己新建一个事务
下面测试SUPPORTS
清空表 运行测试
结果
继续测试
清空表 运行测试
结果
Spring事务传播中
SUPPORTS:如果当前有事务,则使用事务,如果当前没有事务,则不使用事务,适用于查询
关于REQUIRED和SUPPORTS是比较常用的
REQUIRED一般用于增删改
SUPPORTS一般用于查询即可
下面测试MANDATORY
清空表运行测试 和原先的REQUIRED和SUPPORTS的报错有区别 原先是/ by zero
现在是
继续测试
清空表 运行测试 报by zero
Spring事务传播中
MANDATORY:该传播属性强制必须存在一个事务,如果不存在则抛出异常
下面演示REQUIRES_NEW
清空表测试 还是by zero错误
REQUIRES_NEW
意思开启一个新的事务,在我的事务里,如果报错了,会回滚,但是与外层事务无关
这里注意和REQUIRED的区分比如说,以便更好理解REQUIRED_NEW
清空测试
REQUIRED是在同一个事务 REQUIRED_NEW是新建一个事务
NOT_SUPPORTED和NEVER:都表示不支持事务,不管当前有没有事务,我反正当他没有事务
演示一下,下面表示的意思就是父方法没有事务,而自己本身又不支持事务
猜测就是saveParent成功saveChild1成功,saveChild2失败
清空表,测试运行
继续测试 外层有事务
清空表 运行测试
原因是外层用了事务,报错了,对于外层来说,所有都要回滚 因此saveParent虽然成功了,但是子方法报错,因此回滚,而在子方法中又有NOT_SUPPORTED .....因此child1成功,child2报错,因我不支持事务...
NOT_SUPPORTED:如果当前有事务,则挂起,自己不启用事务,一般用于查询
NEVER:没有事务,如果外层有事务会抛出一个异常
如上图这样就会抛出一个状态异常
下面这个报正常的错误by zero,且因不支持事务 child1成功 child2失败
NESTED:当前有一个事务存在的前提下,他会开启一个嵌套事务,父子事务.否则如果当前没有事务,他的作用和REQUIRED一样
NESTED和REQUIRED_NEW是反作用的
NESTED注意下,如果外层有事务,外层事务可以try catch,避免因NESTED事务引起整体回滚
1.什么是事务?
-
事务(TRANSACTION) 是作为单个逻辑工作单元执行的一系列操作。
-
多个操作作为一个整体向系统提交,要么都执行,要么都不执行。
-
事务是一个不可分割的逻辑单元。
2.事务的特性(ACID)
-
原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
-
一致性(Consistency) 事务前后数据的完整性必须保持一致。
-
隔离性(Isolation) 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
-
持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
3.什么是脏读,不可重复读,幻读?
-
脏读:简单来说,就是一个事务读取到了另一个事务未提交的数据。
-
不可重复读:就是说,比如在A事务中进行多次相同的查询,B事务在A事务多次查询之间修改对应表中的数据,导致A事务多次读取的结果不一致。
-
幻读:举例来说,就是A事务将表中'性别'列的值都更改为1,B事务在A事务修改之后又添加了一条记录,而'性别'的值为0,回过来A再查询所以的记录时会发现有一条记录的'性别'为0,这种情况就是所谓的幻读
4.事务的四种隔离级别
-
ISOLATION_READ_UNCOMMITTED:读未提交
-
ISOLATION_READ_COMMITTED:读已提交
-
ISOLATION_REPEATABLE_READ:可重复读
-
ISOLATION_SERIALIZABLE:串行化
5.四种隔离可以解决的问题
6.事务的七种传播行为
什么是事务的传播行为:事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播。
-
PROPAGATION_REQUIRED 表示当前方法必须在一个具有事务的 上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。( 如果被调用端发生异常,那
么调用端和被调用端事务都将回滚)
-
PROPAGATION_SUPPORTS 表示当前方法不必需要具有一个事务 上下文,但是如果有一个事务的话,它也可以在这个事务中运行
-
PROPAGATION_MANDATORY 表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常
-
PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
-
PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。
-
PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常
-
PROPAGATION_NESTED表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中 ,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation. required的一样