mysql 读锁和写锁

读锁:又称共享锁(S锁)。若事务T对数据对象A(某一资源)加上S锁,则事务T可以读A但不能修改A。其它事务也只能读A但不能修改A。并且,其他事务只能再对A加S锁,不能加X锁,除非T释放A上的S 锁。简单的说,自己只能读,别人也只能读。

写锁:又称排他锁(X锁)、独占锁。若事务T对数据对象A(某一资源)加上X锁,事务T可以读A也可以修改A。其它事务不能读A也不能修改A。并且,其他事务不能再对A加任何锁(共享锁或排他锁),直到T释放A上的锁。简单的说,自己可读可写,别人不可读不可写。

行级锁操作

加排它锁:select ...for update

加共享锁:select ... lock in share mode

几个注意的点

  1. mysql InnoDB引擎的数据库,增删改操作默认都会加排他锁,而查询不会加任何锁。
  2. 自己对某一资源加共享锁,别人也可以再继续加共享锁,即多个共享锁可以共存。
  3. 数据库同一资源上,共享锁和排他锁不能共存,排他锁和排他锁不能共存。
  4. 同一资源上,要么不存在任何锁,要么存在单个或多个共享锁,要么存在单个排它锁。

准备测试数据

测试for update 排他锁

现在我们对id=1的数据行进行排他查询,这里会使用BEGIN开启事务,而不去COMMIT提交事务,这样做是为了保证锁不被释放,因为提交事务或回滚事务都会释放锁。

窗口1

此时会查询到一条数据,现在打开另一个查询窗口,对同一数据分别使用排他查询和共享查询。

排他查询:

结果:一直处于阻塞状态,没有返回查询结果集。

 

共享查询:

结果:也是一直处于阻塞状态,没有返回查询结果集。

分析:一个事务中的查询加了排它锁,且事务没有提交。另一个事务中的排他锁查询和共享锁查询都会处于阻塞状态。这是因为id=1的数据已经被加上了排他锁,并且该锁还未释放,阻塞表明是在等待排他锁释放。另外,说明一下,第二个窗口下的查询操作并没有开启一个事务,但属于其它事务中的查询。Why?因为在默认的自动事务提交设置下 ,select 同Update、Insert、Delete一样都会启动一个隐式的事务。窗口1中的事务是显示事务的使用。

 

窗口2中直接查询呢?

结果:直接查询可以查询到数据,不受影响。

窗口1中打开事务提交注释,窗口2中再排他锁查询或共享锁查询:

结果:窗口1中事务一旦提交,窗口2中阻塞状态立刻解除。

mysql事务管理

在 MySQL 中默认情况下每一条增、删、改 SQL 语句都是一个单独的事务,语句执行完后自动提交事务。如果业务中有多条 SQL 语句就需要使用事务相关的 SQL 语句来手动的开启、提交事务。

 

测试LOCK IN SHARE MODE 共享锁

我们再看一下,一个事务中加了共享锁,在其他事务查询中也加共享锁或不加锁的情况。

窗口1中共享锁的事务查询,且没有提交事务

窗口2中测试直接查询

结果:可以查出数据。

 

窗口2中测试共享锁查询

结果:可以查出数据。

 

窗口2中测试排他锁查询

结果:查询处于阻塞状态。

分析:一个事务中的查询加了共享锁,且没有提交事务,另一个事务中的不加锁查询和共享锁查询是可以查到数据的,但排他锁查询不可以,因为排他锁与共享锁不能共存于同一数据上。可以这么理解,排它锁是一种独占的锁,数据只能被自己独占,所以,也就不能存在其他锁了。

 

InnoDb 锁机制

最后我们验证一下上面所说的mysql InnoDb引擎中update、delete、insert语句会自动加排他锁的问题。

窗口1,事务中进行更新操作,不提交事务

结果:数据并没有更新。

窗口2中无锁查询

结果:查询到的依然是旧数据。

窗口2中共享锁查询

结果:查询处于阻塞。

窗口2中排他锁查询

结果:查询处于阻塞。

分析:一个事务中进行了修改操作(update、insert、delete),且没有提交事务。另一个事务中的直接查询(无锁查询)可以查到旧数据,排他锁查询和共享锁查询处于阻塞状态。这说明mysql数据库自动加上排他锁了。

窗口1提交事务,窗口2再排它锁查询

结果:事务2中的查询立刻解除阻塞状态,查到最新数据。

最后小结

1)一个事务中的查询加了排它锁,且没有提交事务。另一个事务中的排他锁查询和共享锁查询都会处于阻塞状态。

2)一个事务中的查询加了共享锁,且没有提交事务。另一个事务中的不加锁查询和共享锁查询可以查到数据,但排他锁查询不可以。

3)mysql InnoDB引擎的数据库,update、delete、insert 都会自动给涉及到的数据加上排他锁,select 语句默认不会加任何锁。

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值