MySQL锁与事务隔离
1.理解锁与事务隔离的关系
1.排他锁(X锁) |
----------Read uncommitted(读未提交)----------(存在脏读问题)
2.共享锁(S锁) |
解决脏读问题(甲修改了数据,却没有将数据提交或回滚了数据,乙读到了甲修改后的‘错误的数据’而不是数据库中现在真实存在的数据约定:
- a. 两双方每次在读取数据前都需要获取到共享锁,读取完毕后立即释放共享锁。
- b. 如果一个数据加了X锁就无法在加S锁,同样如果加了S锁,也无法再加X锁,但可以加S锁。
----------Read committed(读已提交)----------(存在不可重复读问题)
3.到事务提交前后才释放锁 |
---------- Repeatable read(可重复读)----------(存在幻读问题)
4.串行化(在一方提交事务前,另一方无法操作) |
解决幻读的问题。甲查询了某条数据如:
select * from User where id = 1
发现数据不存在,之后甲在表中插入了一条如
insert into User(id, name) values (1, '张三')
甲再去查id=1的数据,发现竟然又有了!
间隙锁同样也是有防止幻读的作用(防止在查询某个范围的记录时有人在这个范围内插入新的数据,而使前后的查询结果不一致)。
值得注意的是,事务隔离的RR级别只对已存在数据有保护作用,而无法防止新的数据插入,这是两者隔离的差异
------------ Serializable(串行化)--------------
高级别的事务隔离,必会造成数据库的并发性变差,因此再非必须情况下,可将事务隔离级别调低。MySQL的默认事务级别使RR,为了获取更高的并发能力,MySQL还提供了一种MVCC(多版本并发控制)方法,解决不可重复读的问题,而且让程序在读数据时不必再加共享锁,只需要找到正确的版本。RC+MVCC能获得很好的并发性能。具体MVCC的实现可以参见:
https://blog.csdn.net/freedom_824/article/details/81591967