Spring事务(二):Spring事务的特点

Easter79
• 阅读 866

事务特性

实现事务必须满足以下四大特性:

  • Atomicity(原子性):构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行。
  • Consistency(一致性):数据库在事务执行前后,完整性没有被破坏。 (转账前后,钱的总数不变)
  • Durability(持久性):事务执行成功后必须全部写入磁盘。
  • Isolation(隔离性):允许多个并发事务同时对数据进行操作,也不会由于交叉执行导致数据不一致。

隔离性 通过MVVC实现(相对应的有MVCC)

原子性、一致性、持久性:通过数据库的redo log、undo log、Force Log at Commit实现

数据库是可以控制事务的传播和隔离级别的,Spring在之上又进一步做了封装,本质上是同一概念。

本文不对数据库事务做过多发散,主要介绍Spring事务相关的部分,数据库事务详情放在另外知识点。

事务隔离级别

事务的四大特性之一:隔离性 ,隔离性在数据库事务中有四种级别。

而Spring则在其基础上加了一种DEFAULT,这是PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。

其他四种隔离级别如下:

Spring事务(二):Spring事务的特点

假设有两个事务交替执行,分别为事务A、事务B

READ_UNCOMMITTED未提交读

事务A做了数据的更改,而事务B能看到事务A未提交的更新数据;

这种隔离级别可能会产生脏读,比如事务A把数据更改撤销了。

READ_COMMITTED提交读

事务A做了数据的更改,事务B只有等事务A提交更改数据后,才能读到新数据。

这种隔离级别可能会产生不可重复读,比如事务B在事务A提交前读第一次,提交后读第二次,读到的数据可能不一致。

REPEATABLE_READ可重复读

可重复读是Mysql InnoDB默认隔离级别。

事务B开始了事务,不管事务A是否提交修改的数据,事务B多次读到的数据都是原先一致。

这种隔离级别可能会产生幻读,比如注解为id的数据:

事务A:select * from users where id = 1; //先看看id是否存在

事务B:insert into users(id, name) values (1, '事务B拥有'); //事务B占用了id=1

事务A:insert into users(id, name) values (1, '事务A拥有'); //事务A继续查id=1,还是空的,但是执行插入报错

事务A发生了幻读,读的是鬼影。(这里容易混淆,不可重复读侧重表达 读-读,幻读侧重表达 读-写)

SERIALIZABLE可串行化

对事务A读取到的数据进行加锁,事务B无法对该数据做修改操作,会阻塞住。只有等A事务提交事务后,修改操作才会执行。

隔离级别越高,对并发的影响就越大。可串行化容易导致超时和锁争用问题。

事务隔离级别设置

在Spring种,通过[@Transactional](https://my.oschina.net/u/3770144)注解的isolation属性,就可以设置当前方法的事务级别

Spring事务(二):Spring事务的特点

Spring在开启事务时,会对当前会话设置事务隔离级别;所以当Spring设置的隔离级别和数据库的隔离级别不一致,Spring的隔离级别会生效。

Spring事务传播机制

Spring通过 AOP环绕通知进行拦截 来实现事务,我们不需要关心事务的开始、提交、回滚,只需要在方法上添加[@Transactional](https://my.oschina.net/u/3770144)注解就可以了。

但是带事务的方法A调用普通方法B,算不算同一个事务呢?异常了是否会一起回滚呢?诸如此类问题,事务传播机制就能解决。

通过[@Transactional](https://my.oschina.net/u/3770144)注解的propagation=Propagation.XXXX属性,就可以设置事务传播机制。机制类别有以下:

假设 方法A 调用了 方法B

REQUIRED(默认机制)

Spring事务(二):Spring事务的特点

  • 方法B设置了REQUIRED,如果方法A有事务,方法B就加入当前事务,合并为一个事务(如上图)
  • 如果方法A没有事务,方法B则会自己新键一个事务

SUPPORTS

  • 方法B设置了SUPPORTS,如果方法A有事务,方法B就加入当前事务,合并为一个事务
  • 如果方法A没有事务,则方法B不开启事务

NOT_SUPPORTED

  • 方法B设置了NOT_SUPPORTED,如果方法A有事务,方法A的事务会被挂起。方法B以非事务的状态执行完,再继续执行方法A的事务。
  • 用于缩小事务范围的场景,将一些无需事务包围的代码写到NOT_SUPPORTED级别的方法中。

MANDATORY

  • 方法B设置了MANDATORY,如果方法A有事务,方法B就加入当前事务,合并为一个事务
  • 如果方法A没有事务,则会抛出异常,保证上下文调用代码不要遗漏事务。

NEVER

Spring事务(二):Spring事务的特点

  • 方法B设置了NEVER,如果方法A有事务,则抛出异常

REQUIRES_NEW

Spring事务(二):Spring事务的特点

  • 方法B设置了REQUIRES_NEW,如果方法A有事务,方法A的事务会被挂起。方法B创建一个新的事务执行,执行完后再继续执行方法A的事务。
  • 方法A和方法B是两个单独的事务,自己的事务出现问题只回滚自己的事务。

NESTED

Spring事务(二):Spring事务的特点

  • 方法B设置了NESTED,如果方法A存在事务,方法B就会称为A事务的子事务。方法B执行结束后并不会提交,等方法A结束后才提交。
  • 如果方法A没有事务,方法B则新建事务。
  • 如果方法B异常,方法A正常提交;如果方法A异常,方法B回滚。

事务失效场景

数据库引擎不支持

MyISAM不支持事务,需要事务的一般用InnoDB引擎

没有被Spring容器管理

数据源没有配置事务管理器

Spring事务(二):Spring事务的特点

非public方法

[@Transactional](https://my.oschina.net/u/3770144)注解只能添加到public方法上

异常被捕捉

需要抛出异常,事务才能回滚

抛出异常类型错误

默认捕捉的是RuntimeException,而抛出的为Exception

Spring事务(二):Spring事务的特点

自身调用

只有在外部调用事务才会生效

  1. 一个普通方法调用一个事务方法

    Spring事务(二):Spring事务的特点

  2. 一个事务方法调用另一个事务方法

    Spring事务(二):Spring事务的特点

    • spring是通过代理来管理事务的,同类调用没有走代理

解决方式就是改为外部调用,拆成两个Service

Spring事务(二):Spring事务的特点

如果非要在内部调用,可以使用代理对象去调用

Spring事务(二):Spring事务的特点

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
LosAngel LosAngel
3年前
golang实现MySQL数据库事物的提交与回滚
MySQL事务主要用于处理操作量大,复杂度高的数据。在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务。事务用来管理insert,update,delete语句,事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部不执行。一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicit
Wesley13 Wesley13
3年前
mysql 事物四大特性和事物的四个隔离
1、事物四大特性(ACID)1.原子性(atomicity):一个事务必须视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。2.一致性(consistency):数据库总数从一个一致性的状态转换到另一个一致性的状态。3.隔离性
Wesley13 Wesley13
3年前
MySql学习17
一.数据库事务的四大特性(ACID)如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性:原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操
Wesley13 Wesley13
3年前
MySQL transaction
MySQLtransaction(数据库的事务)数据库事务(DatabaseTransaction),是指作为单个逻辑工作单元执行的一系列操作。要么完全执行,要么完全地不执行。ACID事务必须具备ACID四个特性原子性(Atomicity)原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。一致性(Consistency)
Wesley13 Wesley13
3年前
MySQL知识体系——事务
ACID(事务的四大特性)    四个特性中,最重要的就是一致性。由原子性,隔离性,持久性来保证。(以下描述用例:用户A、B、C分别在银行拥有500元存款)    原子性(Atomicity)        事务是一个不可分割的工作单元,事务中的操作要么全部COMMI
Wesley13 Wesley13
3年前
MySQL 事务的四大特性ACID介绍
事务的四大特性(ACID)1、原子性(Atomicity)事务是一个不可分割的单位,事务中的所有SQL等操作要么都发生,要么都不发生。2、一致性(Consistency)事务发生前和发生后,数据的完整性必须保持一致。3、隔离性(Isolation)当并发访问数据库时,一个正在执行的事务在执行完毕前,对应其他的会话是不可见的,多个并发事
Wesley13 Wesley13
3年前
MySQL常见问题
事务四大特性原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态一致性:如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的;隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。
事务的ACID,隔离级别,脏读,幻读和不可重复读
事务的ACID原子性(atomicity)一个事务中执行的sql语句,要么全部成功,要么全部失败,不可能一部分成功。一致性(consistency)事务执行前和执行后数据一致,也就是说事务中的sql语句不能只执行一部分。这种请款一般发生在事务异常中断,服
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k