常考面试题(3)-数据库的事务传播和隔离级别

1.什么是事务传播行为
当事务方法被另外一个事务方法调用时,必须指定事务如何传播的。例如:方法可能继承现有的事务,或者开启一个新的事务,并在自己的事务中运行。Sping定义了7种事务传播类型。

传播属性描述
REQUIRED如果有事务在运行,当前的方法就在这个事务中运行,否则,就启动一个新的事务,并在自己的事务中运行(默认值)
REQUIRES_NEW当前方法必须启动新的事务,并在它自己的事务中运行,如果有事务正在运行,应该将他挂起
SUPPORTS如果有事务在运行,当前的方法就在这个事务中运行,否则它可以不运行在事务中
NOT_SUPPORE当前的方法不应该运行在事务中,如果有运行的事务,将它挂起
MANDATORY当前的发给发必须运行在事务内部,如果没有正在运行的事务,就抛出异常
NEVER当前的方法不应该运行在事务中,如果有运行的事务,就抛出异常
NESTED如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则,就启动一个新的事务,并在它自己的事务内运行

例如:现在我去买书这个操作 数据库中有3张表 一个书的库存表,一个书的单价表 ,一个我的账号余额表。

下面是伪代码:
@Transactional
public void buy(int userId,String book){
  //获取图书价格
  //更新图书库存
  //更新账号余额
}

@Transactional
public void checkout(int userId){
  List<String> list = new ArrayList<String>();
  list.add("50"); 
  list.add("60");for(String book:list){
   buy(userId,book)
}
}

我们现在要买两本书,一本50元,一本60元,而我目前的账号余额为100元,因为使用默认的REQUIRED事务,所以buy中用的事务是checkout中的事务,buy方法调用了两次,第一次成功购买,而第二此因为账号余额不足buy方法出现异常,checkout中事务回滚,所以都不会购买成功,而如果buy中使用的是@Transactional(propagation=Propagetion.REQUIRES_NEW),那么每次调用buy方法都会开启一个新的事务,那么至少会购买成功一本书。

2.什么是数据库的隔离级别
了解隔离级别之前,必须要先了解数据库事务并发问题
目前有两个事务t1和t2
(1).脏读:
t1将某条记录age从20改为了30
t2读取了age为30
t1出现异常事务回滚
t2读取到的就是一个无效的值

(2).不可重复度
t1读取age值20
t2将age修改为30
t1再次读取值为30

(3).幻读
t1读取表1中的部分数据
t2向表中插入了新的行

那什么是数据库的隔离级别呢:
数据库必须有隔离并发运行各个事务的能力,使他们不会相互影响,避免各种并发问题,一个事务与其他事务隔离程度称为隔离级别,隔离级别越高,数据一致性越好,但是并发性越弱
(1).读未提交
运行t1读取t2未提交的修改
(2).读已提交
要求t1只能读取t2已经提交的修改
(3).可重复读
确保t1可以多次从一个字段中读取相同的值,即t1执行期间禁止其它事务对这个字段进行更新
(4)串行化
确保t1可以多次从一个表中读取相同的行,在t1执行期间,禁止其他事务对这个表进行添加,删除,更新操作,可以避免任何并发问题,但是性能十分低下
在这里插入图片描述
在这里插入图片描述
例子:比如模拟查询图书价格
编号为 1的图书 价格为 50

下面是伪代码
@Transactional(propagation=Propagetion.REQUIRED,isolation=Isolation.Default)
   public void query(){
   double bookPrice =bookDao.query("1");
   double bookPrice2 =bookDao.query("1");
   
}

我们在bookPrice那打一个断点,启动debug模式,在debug模式中bookPrice价格为50 没有错 ,现在我们手动进入数据中将价格修改为500并提交,因为我是用的是mysql数据库,mysql默认的隔离级别为可重复读,所以第二次查询的结果还是50。而如果将isolation属性改为Isolation.READ_COMMITTED(读已提交),依然重复上面的步骤,第一次读取的是50,第二次读取的就是修改过后并且提交了的值500. 读已提交这种隔离级别也是开发中常用的隔离级别。

最后总结一下 并不是隔离级别越高越好,READ_COMMITTED是开发常用的隔离级别。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值