事物隔离级别


1.未提交读。当其他事物未commit时,当前事物可以读取其他事物已修改的数据


2.已提交读。当其他事物未commit时,当前事物不可以读取其他事物修改的数据读取到的是其他事物未开始之前的数据。如果A事物修改了某条数据,而当前事物B在A开始之前和Acommit之后分别读取该条数据结果必然不同。因此成为不可重复读。


3.可重复读。mysql默认事物隔离级别。如果A事物修改了某条数据,而当前事物B在A开始之前和A commit之后分别读取该条数据结果相同。读取的都是A事物开始之前的数据值。因此成为可重复读。


   这种模型并发量高情况下很可能会出现问题,比如一个生成订单的场景,简单来说有三步


1.查询数据库商品库存是否充足


2.如果库存充足,减库存


3.生成订单




假如两个线程同时开启事物方法 ,每个都是购买50件商品,库存一共有99件


线程A走到第一步,查询到库存数量99大于50,走到第二步判断是否充足,判断结果为充足,此时准备减库存,cpu时间片用完,挂起


线程B查询到的是99,判断库存充足准备减库存,cpu时间片用完,挂起。


线程A继续执行用99-50 ,库存数为49,然后执行完后续sql语句,提交事物


此时线程B获取到cpu时间片,因为之前已经判断过可以减库存了(if(stock>count){//减库存 } )将执行减库存操作 ,用49-50,库存就为负了





要解决这个问题,就需要在一个事物执行完之前,另一个事物完全等待,不能进行查询。


如何锁住当前行 ,默认的查询语句select是不会锁住该行的。需要手动在sql语句之后加for update 。需要注意的是查询条件中必须


包含主键或索引,不然锁住的就是全表。