## 数据库事务并发带来的问题 >四大问题:更新丢失、脏读、不可重复读、幻象读 假设张三办了一张招商银行卡,余额100元,分别说明上述情况。 ### 1、更新丢失 一个事务的更新覆盖了另一个事务的更新。事务A:向银行卡存钱100元。事务B:向银行卡存钱200元。A和B同时读到银行卡的余额,分别更新余额,后提交的事务B覆盖了事务A的更新。更新丢失本质上是写操作的冲突,解决办法是一个一个地写。 ### 2、脏读 一个事务读取了另一个事务未提交的数据。事务A:张三妻子给张三转账100元。事务B:张三查询余额。事务A转账后(还未提交),事务B查询多了100元。事务A由于某种问题,比如超时,进行回滚。事务B查询到的数据是假数据。脏读本质上是读写操作的冲突,解决办法是写完之后再读。 ### 3、不可重复读 一个事务两次读取同一个数据,两次读取的数据不一致。事务A:张三妻子给张三转账100元。事务B:张三两次查询余额。事务B第一次查询余额,事务A还没有转账,第二次查询余额,事务A已经转账了,导致一个事务中,两次读取同一个数据,读取的数据不一致。不可重复读本质上是读写操作的冲突,解决办法是读完再写。 ### 4、幻象读 一个事务两次读取一个范围的记录,两次读取的记录数不一致。事务A:张三妻子两次查询张三有几张银行卡。事务B:张三新办一张银行卡。事务A第一次查询银行卡数的时候,张三还没有新办银行卡,第二次查询银行卡数的时候,张三已经新办了一张银行卡,导致两次读取的银行卡数不一样。幻象读本质上是读写操作的冲突,解决办法是读完再写。 ### 解决办法 #### (1)一组事务单元执行加锁(悲观锁) 开启两个十五单元之前认为冲突很严重,先把锁加上。两个事务单元串行。 #### (2)乐观锁并发方案 让版本低的并发更新回滚(事务1比事务2先来,则事务1的版本更低,事务2版本更高) 优点:并发低时性能好 缺点:并发高时失败率高,需要不断重试 可以完成并发方案。 ##### 最后结果 事务2完成 事务1在Bob给Smith加100元的更新环节, 检测到事务1的这一环节的版本号 低于 事务2锁定smith账户数据的版本号, 从而事务回滚。