面试 之 MySql &Spring 事务管理

1 mysql事务隔离级别

隔离级别 脏读 不可重复读 幻读
未提交读(Read uncommitted)
已提交读(Read committed) ×
可重复读(Repeatable read) × ×
可串行化(Serializable ) × × ×
  1. 未提交读(Read Uncommitted):脏读(读取未提交数据)

     B给A转100块钱 ,A查询发现到账100 ,B发现错误,回滚数据,实际A未拿到那100
    
  2. 提交读(Read Committed):不可重复读(前后多次读取,数据内容不一致)

     A查询账户有100元  同时B 取走了A里面50元,A再查询账户只有50元
    
  3. 可重复读(Repeated Read):幻读(前后多次读取,数据总量不一致)

     B查A账户有100元准备想取出来 ,同时A在消费 用了50元,B发现看到是100却取出100失败
    
  4. 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

乐观锁 &悲观锁

乐观锁

更新语句中增加过滤条件,进行版本的判断

begin;
select name,realname,utime from account where name='aaak';
aaak  ak  2018-06-12 18:20:06
update account set utime =123123 where name='aaak' and realname='aaak  ';
commit;

悲观锁

悲观锁的特点是先获取锁,再进行业务操作 通常用select … for update操作来实现悲观锁

BEGIN;
SELECT * FROM account where id = 1 FOR UPDATE;
UPDATE account set `realname` = "aak" where id = 1;
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。

因为InnoDB对于行的查询都是采用了Next-Key
Lock的算法,锁定的不是单个值,而是一个范围,按照这个方法是会和第一次测试结果一样。但是,当查询的索引含有唯一属性的时候,Next-Key
Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,不是范围。

2 spring事务传播机制和隔离级别

1 spring事务传播机制
类型 解释
REQUIRED 1支持当前事务,如果当前没有事务,则新建事务
2如果当前存在事务,则加入当前事务,合并成一个事务
REQUIRES_NEW 1新建事务,如果当前存在事务,则把当前事务挂起
2这个方法会独立提交事务,不受调用者的事务影响,父级异常,它也是正常提交
NESTED 1如果当前存在事务,它将会成为父级事务的一个子事务,方法结束后并没有提交,只有等父事务结束才提交
2如果当前没有事务,则新建事务
3如果它异常,父级可以捕获它的异常而不进行回滚,正常提交
4但如果父级异常,它必然回滚,这就是和 REQUIRES_NEW 的区别
SUPPORTS 1如果当前存在事务,则加入事务
2如果当前不存在事务,则以非事务方式运行,这个和不写没区别
NOT_SUPPORTED 1以非事务方式运行
2如果当前存在事务,则把当前事务挂起
MANDATORY 1如果当前存在事务,则运行在当前事务中
2如果当前无事务,则抛出异常,也即父级方法必须有事务
NEVER 1以非事务方式运行,如果当前存在事务,则抛出异常,即父级方法必须无事务

一般用得比较多的是 PROPAGATION_REQUIREDREQUIRES_NEW
REQUIRES_NEW 如果save()中的代码抛出异常,并且被捕获,commit()中的其他代码不会roll back ,如果其他代码抛出异常,而且没有捕获,不会导致save()回滚

2隔离级别

数据库是可以控制事务的传播和隔离级别的,Spring在之上又进一步进行了封装,可以在不同的项目、不同的操作中再次对事务的传播行为和隔离级别进行策略控制。

  1. Spring会在事务开始时,根据你程序中设置的隔离级别,调整数据库隔离级别与你的设置一致。
  2. 当使用Serializable级别时,Mysql在执行SQL时会自动修改为select … lock in share mode, 即使用共享锁。此时允许同时读,但只允许一个事务写,且锁的是行而不是整张表。
  3. 如果数据库不支持某种隔离级别,那么Spring设置了也无效。
  4. 当使用Serializable级别时,如果两个事务读写的不是同一行,那么它们是互不影响的。如果操作同一行记录,那么允许同时读,但如果出现一个对此行的写操作,则在写事务没有提交之前,所有的读事务都会被block。

参考:
MySQL 之 InnoDB引擎 Transaction
Spring事务管理与数据库隔离级别的关系
MySQL事务隔离级别和Spring事务关系介绍
Spring事务隔离级别与Mysql InnoDB事务隔离级别的关系

发布了15 篇原创文章 · 获赞 0 · 访问量 404

猜你喜欢

转载自blog.csdn.net/u010020726/article/details/104979811