首先来说下事务,说到事务就不得不说它的四个特性(acid):
一、特性
1.原子性(atomicity):一个事务当作为一个不可分割的最小工作单元,一组操作要么全部成功,要么全部失败。
2.一致性(consistency):必须使数据的一个一致性状态变成另一个一致性状态。举个例子,A和B共有1000元,一人500,他们之间发生了资金上的往来,不管最后各自有多少钱,但是他们的总和还是1000元。
3.隔离性(isolation):在并发的时候,一个事务不能影响到另一事务,相互之间没有任何关系的。
4.持久性(durability):指在事务提交了之后,对数据库中的数据的修改永久的保存下来。
二、事务的隔离级别
1.读未提交(read_uncommited):发生脏读现象-->指一个事务中读取到另一个事务中未提交的数据。解决这种现象,需要将数据库的隔离级别设置为read_commited
2.读已提交(read_commited):会发生不可重复读的现象-->指一个事务中,前后两次查询的数据不一样,在后一次查询到另一个事务对数据进行了更新数据操作并提交了的数据。解决这种情况需要将数据库的隔离级别设置为repeatbale_read。oracle数据库默认的就是这个隔离级别(read_commited)。
3.可重复读(repeatable-read):会发生虚读(幻读)现象-->指在一个事中,前后两次查询的数据不一样,在后一次的查询到另一个事务对数据库做了新增数据并提交了的数据。解决这种情况需要将数据库的隔离级别设置为serializable,mysql数据库的默认级别就是这个(repeatable_read)。
4.序列化(serializable):serializable是事务的最高隔离级别,事务一个个的执行,比较消耗数据库的性能,几乎不用。
注意:不可重复读针对的是update操作,虚读(幻读)针对的是insert操作。这一点容易让人迷惑。
下面来简要的说下Spring中的事务,spring中的事务主要使用的声明式事务,什么不懂什么是声明式事务,事务分为编码式事务,和声明式事务,编码式事务就是你要自己手动的编写事务,获取jdbc的连接啊,设置事务自动提交为false啊,手动commit啊,出现了错误rollback啊。声明式事务就是Spring中的事务处理,使用aop啊,或者注解啊,注解的底层使用的也是aop。
来主要说说@Transactional 中的几个属性代表了啥
propagation 事务的传播机制,下面解释下propagation的几个取值代表什么意思,(默认的取required)
required :没有就创建一个transaction,有的话就不创建
required_new :重新创建一个属于自己的事务,原来有的事务将被挂起
mandatory: 该方法只能存在一个已存在的事务中,自己不能发起事务,如果不存在事务,会抛出异常
supports: 如果存在事务就在此事务下执行,如果没有,就在无事务下执行
not_supported:声明不需要事务,如果关联到一个事务,会将这个事务挂起,调用结束过,原事务接着执行
never:该方法绝不能在事务里面执行,如果关联到事务就报错,该方法只能在无事务里面执行
nested:如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务
isolation:事务的隔离级别,它的值就是上面我已经介绍过的几个(read_uncommited,read_commited,repeatable_read,serializable),默认是取数据库的隔离级别,就是你使用哪种数据库,它的隔离级别就是哪个,好比你用的oracle,就是read_commited,或者你用的是mysql,就是repeatable_read.
rollback-for:默认的当程序抛出unchecked的例外(runtimeException以及它的子类),会发生数据的回滚,可以自定义需要哪种异常的情况下回滚数据
read_only :表示只读,不能对数据进行cud.
timeout:表示事务的超时时间:默认的取数据库设置的事务超时时间,如果没有就是无限长,没有时间限制。
no_rellback_for:和rollback_for相反。
注意:@Transactional 作用在方法上的时候,只能作用在Public修饰的方法上。作用在其他的访问控制符上的方法,事务不会生效,也不会报错。
参考: https://www.cnblogs.com/yepei/p/4716112.html