事务的四大特性,传播行为以及应用场景
Posted barry3
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事务的四大特性,传播行为以及应用场景相关的知识,希望对你有一定的参考价值。
一、事务的四大特性:
* ACID: 原子性,一致性,隔离性,持久性
* 原子性:要不一起成功,要不一起回滚;
* 一致性:对数据的操作,数据总数不变 ; (转账业务 A 转账B 20元,但是A B的总计还是原来的数值)
* 隔离性:一个事务不会影响另一个事物;
* 持久性:事务一旦提交对数据库的影响是持久的;
二、事务的隔离级别:
- 读未提交Read uncommitted
- 读已提交Read committed
- 可重复读Repeatable read
- 串行化Serializable
(一)读未提交 Read uncommitted:
一个事务读了另一个事务的未提交内容;可能会出现脏读、不可重复读、幻读;
(二)读已提交Read committed:
在读取的时候,其他事务可以进行更改;避免了脏读;
示例:事务a先读取某一条数据,事务b更新该条数据,当事务a再次读取数据的时候,数据发生改变;造成不可重复读;
(三)可重复读 Repeatable read:
在读取的时候,其他事务不可以进行更改;避免了出现脏读、不可重复读;但是可能会出现幻读;事务A读到的数据是一个数据集,不在是某一行数据,读取到打印期间,事务B增添了 一条新的数据,这个时候A打印的结果包含之前没有读取到的新数据集;
(四)串行化 Serializable:
避免了脏读、不可重复读、幻读 ,但是执行相率不高,相当于锁表;
扩展:
Oracle只支持Serializable串行化和Read committed读已提交
mysql默认是Repeatable read可重复读
Oracle默认是Read committed读已提交
Mysql事务隔离级别的设置:
1. 在MySQL数据库中查看当前事务的隔离级别:1select @@tx_isolation;
2. 在MySQL数据库中设置事务的隔离级别:1set [glogal session] transactionisolationlevel 隔离级别名称;
参考文章:
三、Spring中的七中事务传播行为:
1.PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
2.PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
3.PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。;eg:话费充值业务 扣款和订单其中一个异常则整个处理器回滚;
4.PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。;
示例:log() 日志事务,不受当前事务当前事务失败还是成功都需要写入日志
5.PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6.PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
示例:在订单的售后处理中,更新完订单金额后,需要自动统计销售报表,而统计报表太耗时,所以不在事务中操作;设置为 Never
7.PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
示例:在银行新增银行卡业务中,需要执行两个操作,一个是保存银行卡信息,一个是登记新创建的银行卡信息,其中登记银行卡信息成功与否不影响银行卡的创建。登记银行卡信息的事务不是必须的所以是否会滚不影响,可以设置为NESTED,而保存卡信息要和整个事务一起 提交或回滚 因此可以设置为required或者mandatory
只读事务 :@Transactional(readOnly=true)
Spring 为了忽略那些不需要事务的方法,比如读取数据,这样可以有效的提高一些性能。
事务超时 (Transaction Timeout):@Transactional(timeout = 60)
为了解决事务执行时间太长,消耗太多资源的问题,可以设置一个超时时间。如果该事务支持超过设置的时间,就回滚该事务。
参考文章:
以上是关于事务的四大特性,传播行为以及应用场景的主要内容,如果未能解决你的问题,请参考以下文章