数据库并发事务
事务并发包括:
- 第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖。
- 脏读:一个事务读到另一个事务未提交的更新数据。
- 虚读:一个事务读到另一个事务已提交的新插入的数据。
- 不可重复读:一个事务读到另一个事务已提交的更新数据。
- 第二类丢失更新:是不可重复读的特例,一个事务覆盖另一个事务已提交的更新数据。
?
?
第一类更新丢失时间取款事务转账事务T1开始事务?T2?开始事务T3查询账户的存款余额为1000元?T4?查询账户的存款余额为1000元T5?汇入100元,把存款余额改为1100元T6?提交事务T7取出100元,把存款余额改为900元?T8撤销事务,账户的存款余额恢复为1000元??
?
?
?
脏读时间取款事务转账事务T1开始事务?T2?开始事务T3查询账户的存款余额为1000元?T4取出100元,把存款余额改为900元?T5?查询账户的存款余额为900元(脏读)T6撤销事务,账户的存款余额恢复为1000元?T7?汇入100元,把存款余额改为1000元T8?提交事务?
?
?
?
虚读时间取款事务转账事务T1开始事务?T2?开始事务T3?统计网站注册总数为10000人T4注册一个新用户?T5提交事务?T6?统计网站注册总数为10001人(虚读)T7?到底是哪个统计数据有效,不确定T8???
?
?
?
不可重复读时间取款事务转账事务T1开始事务?T2?开始事务T3查询账户的存款余额为1000元?T4?查询账户的存款余额为1000元T5取出100元,把存款余额改为900元?T6提交事务?T7?查询账户的存款余额为900元T8?存入账户100元,到底是把余额修改为1000元还是1100元??
?
?
第二类丢失更新时间取款事务转账事务T1开始事务?T2?开始事务T3查询账户的存款余额为1000元?T4?查询账户的存款余额为1000元T5取出100元,把存款余额改为900元?T6提交事务?T7?存入账户100元,把余额改为1100元T8?提交事务?
解决事务并发,采用共享锁和独占锁?
解决事务并发问题资源上已经放置的锁第二个事务进行读操作第二个事务进行更新操作无立即获得共享锁立即获取独占锁共享锁立即获得共享锁等待第一个事务解除共享锁独占所等待第一个事务解除独占锁等待第一个事务解除共享锁?
?
死锁例子事务1
begin;
update customers set name='tom' where id=1;
update orders set oreder_number='tom_order001' where Id=1;
commit;
?
事务2
update orders set oreder_number='jack_order001' where Id=1;
update customers set name='tom' where id=1;
commit;
?
?
?
死锁时间事务1事务2T1开始事务?T2?开始事务T3update customers set name='tom' where id=1;
对customers表中ID为1的记录放置独占锁,
只有当整个事务结束才会解除该锁?T4?update orders set oreder_number='jack_order001' where Id=1;
对order表中ID为1的记录放置独占锁,
只有当整个事务结束才会解除该锁T5update orders set oreder_number='tom_order001' where Id=1;
等待事务2解除对order表中ID为1的记录放置独占锁?T6?update customers set name='tom' where id=1;
等待事务1解除对customers表中ID为1的记录放置独占锁?
死锁避免法则:
- 合理安排表访问顺序使用短事务如果对数据的一致性要求不是很高,可以允许脏读。脏读不需要对数据资源加锁,可以避免锁冲突。如果可能的话,错开多个事务访问相同的数据资源的时间,以防止锁冲突。使用尽可能地的事务隔离级别。
?
事务隔离级别隔离级别是否出项第一类丢失更新是否出现脏读是否出现虚读是否出现不可重复读是否出现第二类丢失更新Serializable否否否否否Repeatable Read否否是否否Read Commited否否是是是Read Uncommited否是是是是??
并发性和隔离级别成反比?