一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情
前言
在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的 资源。为保证数据的一致性,需要对 并发操作进行控制 ,因此产生了 锁 。同时 锁机制 也为实现MySQL 的各个隔离级别提供了保证。 锁冲突 也是影响数据库 并发访问性能 的一个重要因素。所以锁对数据库而 言显得尤其重要,也更加复杂。
今天这篇文章来讲下并发访问相同记录如何使用锁以及锁之间的情况,在对同一条数据做查询或者操作的时候分为两种情况,一种是读取数据一种是修改数据,所以就会出现读-读,读-写,写-写这三种情况,下面我们来看下mvcc如何对其作出处理。
查看当前隔离级别:show variables like 'transaction_isolation';可重复读,如下图:
表test_index有两条数据如下图:
1.读-读
分别开两个窗口,在两个事务都读取同一批记录的情况下加共享锁,执行select * from test_index lock in share mode;,可以看到窗口一和窗口二都可以查询出数据,如下图:
由此可以推断出读取请求共享锁不会造成事务阻塞的情况。
2.读-写
开启事务一,执行SQL:select * fromtest_index lock in share mode;且不提交事务,如下图:
此时开启事务二,执行独占锁SQL:select * from test_index for update;,可以发现事务二一直被阻塞直到达到锁超时时间,如下图:
如果此时事务一及时将事务提交,那么事务二就不会阻塞,如下图:
新开两个事务,事务一修改id为2的desc字段且不提交事务,事务二查询全部记录,如下图:
我们可以发现即使事务一没有加锁也会阻塞事务二,由此可以推断出修改数据的操作默认会加锁,但是如果我们避开id为2的这条记录去查询id为1的记录会发现事务二并没有阻塞,如下图:
由上述现象我们可以推断出只要有写的操作那就会阻塞其他事务,因为写是独占锁。
2.写-写
这种情况掘友们肯定知道结果了,肯定是会阻塞的,因为有写操作的存在必然会阻塞其他事务,开启两个事务,都执行SQL:insert into test_index values(3,'333',now(),'233~',333333);且事务一不提交,会发现事务二阻塞,如下图:
此时如果将事务一提交,会发现事务二执行失败,因为事务一已经新增了id为3的记录了