Spring事务的隔离级别

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

事务隔离级别解决的是多个事务同时调⽤⼀个数据库的问题

事务传播机制解决的是⼀个事务在多个节点(⽅法)中传递的问题

事务的特性:

隔离性:多个事务在并发执行的时候多个事务之间执行的一个行为模式当一个事务执行的时候另一个事务执行的一个执行行为模式是什么

1)A原子性一个事务中的所有操作要么全部执行成功要么全部执行失败要么全部执行要么全部不执行不会结束在某一个中间环节事务在执行的时候发生错误会被回滚到事务执行之前的状态就好像这个事务从来没有发生过一样

2)C一致性在事务开启和事务结束之后对数据库的完整性没有发生破坏转账前后总钱数没有发生变化张三的钱数和李四钱数在转账前后的总钱数是不会发生改变的

3)I持久性事务处理结束之后对数据的修改就是持久的数据永久地被存下来关机重启之后也不会丢失系统故障也不会丢失

4)D隔离性数据库允许多个并发事务同时对其数据进行读写和修改能力隔离性可以防止多个事务并发由于交叉执行而导致数据的不一致事务隔离分为四种级别多个单个事务同时并发执行的时候多个事务之间行为模式

5)而事务的传播机制是指当一个程序调用链里面有多个方法的时候多个方法进行相互调用的时候多个方法又有自己的事务的时候这就是嵌套事务当程序中出现嵌套事务之后嵌套事务的行为模式Spring 事务传播机制定义了多个包含了事务的⽅法相互调⽤时事务是如何在这些法间进⾏传递

一个讲的是列是事务传播机制

一个讲的是行是事务隔离级别

6)为什么要设置事务的隔离级别

设置事务的隔离级别是为了保证多个并发事务执行更可控更符合操作者预期的事务的隔离级别就是为了说为了防止其他的事务影响到当前事务执行的一种策略

7)用咱们的CMD连接数据库:mysql -uroot -p(数据库的密码) 数据库名在客户端执行这个操作就可以进行连接数据库了 

select @@global.tx_isolation,@@tx_isolation,查看当前隔离级别和系统默认隔离级别
@@global.tx_isolation这个就是系统默认的隔离级别,还有咱们的@@tx_isloaction是咱们的当前客户端的默认隔离级别

使用两个客户端来进行演示一下MYSQL的事务的四种隔离级别:

一:脏读问题(读未提交就开始读):

这个对应MYSQL的隔离级别就是read uncommitted

1)表示读未提交也叫做未提交读该隔离级别的事务可以看到其他事务中没有提交的数据而未提交的数据可能会发生回滚我们就把一个事务读到别的事务没有提交的数据称之为脏数据因为该事务隔离级别可以看到其他事务没有提交的数据我们把该隔离级别读到的数据称之为脏数据把这个问题称之为脏读

2)这个是指一个事务B读取到了另一个事务A未提交保存的数据此后这个A事务进行了回滚操作从而导致了B事务读到了一条不存在的脏数据此时B事务读到的就是一个中间态的数据B事务就可能会使用这条脏数据但是后来A事务直接将事务回滚该数据就不存在了

3)我们是可以使用两个MYSQL客户端来进行演示的:

此时我们先将客户端A的事务隔离级别设置成读未提交而B的客户端的默认隔离级别是系统默认的隔离级别:

执行客户端A客户端B
1set session transaction isolation level read uncommited
2start transaction
3start transaction
4insert into city values("西安")
5select * from city(此时我们读到一条数据这个数据就是脏数据
6rollback
7select * from city 啥也读不到

我们发现在我们的事务B新增数据进行完成回滚操作之后我们的客户端A在进行我们此时在city表中是无法进行查询到任何数据的

二)不可重复读问题(写完了读读已提交):

但是从我的理解角度来说同一个时间段不同的查询得到了不同的结果但是读到的数据都是真实的在磁盘的上面进行修改了虽然查询的是不同的结果我们此时的得到的都是数据库中真实的数据只不过我们期望的是两个事务执行时互不影响但是实际上是有很多事务在并发修改数据库我认为不是一个问题因为我时时刻刻地在读到数据库中真实的数据

2.1)这个时候一个事务不可以看到另一个事务未提交的数据了但是可以看到其他事务提交的结果A事务和B事务在执行的时候B未提交的数据A是看不到的

2.2)我们在同一个事务中同一个查询在不同的时间段内得到了不同的结果假设咱们的事务在T1的时候读取到了某一行数据我们在T2时间内再次重新读取到这一行的时候这一行的数据我们发现此时已经被其他事务修改了;

执行客户端A客户端B
1set session transaction isolation level readcommited
2
3select * from city(查询到的是西安的数据)
4

start transaction

5

执行SQL语句:

update city set name="长安" where name="西安“

6commit
7select * from city(此时我们读到的数据是长安)

我们从上述结果中我们发现客户端A被设置成了读已提交的事务隔离级别之后使用相同的SQL两次进行读取到的同一条数据内容是不一样的这就是不可重复读主要是针对修改操作来说的在事务1读取的过程中可以读到其他事务提交的结果

总结:该隔离级别的事务能读到已经提交事务的数据因此他不会出现脏读问题但是在事务执行的过程中可以读到其他事务提交的结果所以在不同的时间的相同的SQL查询的时候可能会得到不同的结果

三:幻读问题:同一个查询在不同时间内出现了不同的结果

1)这就是事务中的幻读问题咱们举个例子来说当我们开启事务之后我们执行第一次select我们进行查询出来了一条语句就类似于幻觉

2)但是当我们再次执行第二次Select查询之后我们查询到了两行第二次返回了第一次的·select查询没有进行返回的一行这一行就类似于幻想行下面我们举个例子来理解一下:

步骤        客户端A客户端B
1set session transaction isolaction level repeatable read
2start transaction
3select * from city where id<5
4start transaction
5insert into city city(id,name) values(2,北京);
6commit
7update city set name="京城” where id=2
8select * from city where id<5

从上述执行流程来看我们最后一条查询语句查出了两条数据客户端A一开始就设置了可重复读的事务隔离级别之后使用相同的SQL却查询出来了不一样的结果第一次查询出了一条数据第二行却查询出了两条数据多出来的这条数据就叫做幻象行所以说在可重复读的情况下可能会出现幻读的问题

最后总结:

1)脏读是读到了其他事务未提交的数据不可重复读和幻读是已经读到了其他事务提交修改的数据不可重复读是读到了其他事务修改的数据

2)但是幻读是读取到了其他事务新增或者删除的幻象行数据

3)幻读和不可重读描述的侧重点是不一样的幻读描述的是新增或者删除操作不可重复读描述的是修改操作的会强制事务进行排序

脏读:一个事务读取到了另一个事务修改的数据之后后一个事务又进行了回滚操作从而导致第一个事务读到的数据是错误的

不可重复读:一个事务两次查询的结果不同因为在两次查询中间有另一个事务把数据给修改了

幻读:一个事务两次查询得到的结果集不同因为在两次查询过程中有另一个事务新增了一部分数据

咱们Spring的事务隔离级别:解决的是多个事务共同调用数据库的问题

需要进行事务的隔离级别只需要进行设置@Transaction里面的isolation属性即可

@Transactional(isolation = Isolation.DEFAULTtimeout =60)

1)Isolation.DEFAULT:以连接的数据库的事务隔离级别为主使用链接的对应数据库的隔离级别如果使用MYSQL那么事务隔离级别就是read committed

2)Isolation.READ_UNCOMMITTED:读未提交可以读到未提交的事务是存在脏读的

3)Isolation.READ_COMMITTED:读已经提交只能读取到已经提交的事务解决了脏读但是还是存在着不可重复读的问题

4)Isolation.REPEATABLE_READ:可重复读解决了不可重复读的问题但存在着幻读这是MYSQL的一个默认隔离级别

5)Isolation.SERIALIZABLE:这是串行化可以解决所有的并发问题但是性能太低所有事务来了串行执行一个一个执行直接就没有并发事务

注意:

1)当Spring中设置了事务隔离级别和连接的数据库事务的隔离级别的发生冲突的时候那么以Spring事务隔离级别为准

2)当Spring中的事务隔离级别的实现是依靠连接数据库支持事务隔离级别的基础比如说MYSQL5.1引擎是MYSIMMYSQL5.1默认时是不支持事务和事务隔离级别的时候当MYSQL使用不支持事务的存储引擎的时候所以在程序里面是不支持事务和事务隔离级别的

3)设置当前客户端的隔离级别:set session transaction isolation level +隔离级别

1)可重复读:它能确保同一事务多次查询的结果一致但也会有新的问题比如此级别的事务正在执行时另一个事务成功的插入了某条数据但它每次查询的结果都是一样的因为他已经解决了不可重复读的问题虽然原有数据没有被修改但是新增或者减少了数据

2)所以会导致查询不到这条数据自己重复插入时又失败因为唯一约束的原因明明在事务中查询不到这条信息但自己就是插入不进去这就叫幻读

3)串行化:会强制事务排序使之不会发生冲突从而解决了脏读、不可重复读和幻读问题但因为执行效率低所以真正使用的场景并不多

事务传播机制:

1)当有多个嵌套事务的时候多个嵌套事务之间的行为模式我是把所有小的事务当成一个大的事务还是各自为正还是一个方法有事务一个方法没有事务到底最终加不加事务当有多个方法嵌套调用的时候多个方法的行为模式

2)当一个程序里面有多个方法的时候多个方法在相互调用的时候多个方法又同时有事务的时候多个事务在相互调用的时候的一个行为模式

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring