mysql中隔离级别和锁有什么关系?

转自 :https://www.wukong.com/answer/6603702542973010183/?iid=43974241203&app=news_article&share_ansid=6603702542973010183&app_id=13&tt_from=mobile_qq&utm_source=mobile_qq&utm_medium=toutiao_ios&utm_campaign=client_share

事务隔离级别,我将它理解为多线程数据隔离级别。大家可以想象一个对象有对其中某个字段的增删改查方法,在多线程的情况下就有很多种解决方案。

第一种:读写都是直接操作该字段,不加同步锁。

第二种:读是操作该字段的副本,写是直接操作该字段,不加同步锁。

第三种:读和写都是操作该字段的副本,不加同步锁。

第四种:读写直接操作该字段,加同步锁。

ps:如果有副本,增删改查都是操作副本

通用方法:commit,将副本数据同步至该字段。

通用方法:rollback,将此事务所有操作了该字段的方法回滚。

于是这类方法,便为分为了四类,分别为读未提交,读已提交,可重复读,串行(中文理解,非要用英文,我手机也打不出来)

扫描二维码关注公众号,回复: 5338180 查看本文章

那么现在开始简单介绍四类隔离级别。

1:读未提交,首先我们开启两个事务,分别为事务A和B,在事务A中更新删除或修改一条数据后,在未commit的情况下,在事务B中可以直接查出来。也就是说事务B是读取的数据而非副本,事务A是操作的数据而非副本。而rollback是将数据还原为事务A在开启时的数据。

2:读已提交,我们同样用A和B,在事务A中更新删除或修改一条数据后,在未commit的情况下,在事务B中查询不到,在commit的情况下,在事务B中可以查询到。也就是说事务B仍然是读取的数据而非副本,事务A操作的是副本,commit的方法是将副本同步至数据。而rollback是将副本还原至事务A在开启时的副本数据。

3:可重复读,还是A和B,在事务A中更新删除或修改一条数据后,在commit的情况下,在事务B中仍然查询不到。也就是说事务B读取的是数据的副本,当然事务A操作的也是副本。这点可以开事务C来验证,将事务C的隔离级别调整为读未提交即可。(大伙可自行验证)

4:串行,所有事务操作串行,也就是事务A没结束的时候,事务B开始也是等待,无法操作。

----------------------------------------------------------

以上重新码完,以下有时间再码,先去忙了。

锁机制

为什么有锁,事务或者不使用事务,在操作数据实体的时候数据库会对数据进行加锁,不加锁引发的问题不需要解释吧?熟悉多线程的都知道。这就像你用hashMap拿去玩多线程。锁和事务的区别就如同一个是字段的同步锁,一个是如何使用该字段或其副本,二者几乎没有关系。

数据库自带的锁分两类

1.共享锁

2.排他锁

增删改默认使用排他锁。

查不使用任何锁,可以在sql最后面添加for update指定使用排他锁,共享锁的语句背不下来,就不写了,网上一大把。

对于同一条数据,只能被加锁一至多个共享锁或一个排他锁。如果数据被共享锁加持,查询默认因未使用锁,可以直接查询。增删改因使用排他锁需要等待共享锁释放才能执行,否则等待。排他锁类似。请反复研读此段第一句话和理解各sql默认的锁。

以上均为业内所谓的悲观锁

其他知识:

乐观锁,人为在数据里面加一个字段作为版本标志,操作前读数据,操作的时候直接以where作为条件,如果更新数量不符合实际数量,则循环读取更新。(个人觉得此解决方案不能叫锁)。

如果数据库支持行锁,那么被加悲观锁时,只会锁几行,其他数据的增删改查不受影响。不支持行锁的数据库就直接是表锁了,也就是该表只能这个sql执行完,另一个才能操作。所以实际情况就算用悲观的排他锁,也并不会多影响性能,加上有redis做查的缓存,其实是能吊打乐观锁的,至少我是这么认为的,毕竟数据库的连接的代价是很大的。乐观的循环查与更新可能对数据库造成毁灭性的打击。

另外事务的隔离级别会影响锁的时长,这个在下目前只听说可重复读及串行的共享锁会延迟到事务结束。但是实测并不会影响。

猜你喜欢

转载自blog.csdn.net/xiaoxianerqq/article/details/82834475