Chinaunix
标题:
请教:mysql 事务与锁策略
[打印本页]
作者:
龙雪刚
时间:
2012-04-10 17:45
标题:
请教:mysql 事务与锁策略
本帖最后由 龙雪刚 于 2012-04-10 17:49 编辑
场景:表A引擎为innodb,现有两个事务T1,T2,默认隔离级为Repeatable Read,autocommit = 1
T1:
{
1:start transaction;
2:update A set name = 'ABC' where ID = 1;
3:select * from A where ID = 1;
4:COMMIT;
}
T2:
{
1:select * from A where ID = 1;
}
请教: 当T1执行完第二步后,执行T2需要等待吗?执行T1中的第三步需要等待吗?希望给出原理。
作者:
飞鸿无痕
时间:
2012-04-10 18:49
当T1执行完第二步后,执行T2需要等待吗?
这个肯定是要等待的,只要T1没有提交,就会给A表的id=1的记录x锁定(假如id为主键的最理想情况)。因为innodb在要更新数据的之前是要获得x锁定的。
执行T1中的第三步需要等待吗?
这个不需要等待,select和update在同一个事务中,因为如果T1的第二步成功执行就表示这个事务已经对A表的id=1的记录有X锁定,
作者:
龙雪刚
时间:
2012-04-11 09:25
回复
2#
飞鸿无痕
呵呵,其实都不需要等待,我也是跟你想的一样才会犯迷糊,才会有了这个贴子。测试版本5.5.15-log MySQL Community Server (GPL),5.0.27-community-nt MySQL Community Edition (GPL)。
作者:
飞鸿无痕
时间:
2012-04-11 10:33
回复
3#
龙雪刚
一会有时间了测试一下,写锁定和读锁是互斥的啊!
作者:
ooooldman
时间:
2012-04-11 10:51
这个应该和隔离级别有关吧,坐等大师测试发数据
作者:
ruochen
时间:
2012-04-11 12:47
测试下就知道了
另外,多考虑下innodb的mvcc是如何实现的
作者:
RogerZhuo
时间:
2012-04-11 13:15
回复
5#
ooooldman
其实innodb里的select是否有锁等待(也就是常说的查询挂起)是和事务隔离级别没有直接关系的, 隔离级一般影响select读取的mvcc的哪个数据版本。
1,对此lz问题,T2查询是否为等待?
就如你所说的一样,T2不会等待,因为一般的查询select是
不会对被查询table添加任何锁
的,也就是查询不会有任何锁等待,哪怕你在T1中直接去掉where子句,对表A加上了排他表锁;
T2也会能正常返回,但以下select不会哟
1.1 SELECT…FOR UPDATE 可以获得一个X锁。
1.2 SELECT…LOCK IN SHARE MODE 可以获得一个S锁。
是表锁,还是行锁(间隙性的)要看你的where子句的列,是否使用了index了。
2, 再看事务隔离级别对select结果的影响,这里就是版主所提的mvcc了
2.1 已提交读, 查询总是读取最新版本数据
2.2 可重复读, 查询只返回事务开始的数据版本
搞个三个事务,做下测试就明白。
也可以通过show innodb engine status\G来查看锁等待, 如果用的是插件的,还有三个元数据表可以看,查下innodb文档吧。
作者:
飞鸿无痕
时间:
2012-04-11 14:13
本帖最后由 飞鸿无痕 于 2012-04-11 14:26 编辑
回复
3#
龙雪刚
测试了,单纯的select不会等待,如果是select加上for update或者lock in share mode的时候会等待!是我以前理解的有点问题,锁那部分还得好好学习一下啊,呵呵!
作者:
龙雪刚
时间:
2012-04-11 14:15
回复
8#
飞鸿无痕
共同学习,我也不是很明白这个锁。
作者:
龙雪刚
时间:
2012-04-11 14:34
《高性能mysql》对MVCC介绍中有这么一句话: Innodb通过对每一行新增创建版本号与删除版本号这两个隐含值来实现MVCC的。 这就使得在大多数读操作都不需要申请锁,因为读操作只需要选择行版本号符合条件的行即可。
这似乎能解释其中的原因。
作者:
龙雪刚
时间:
2012-04-11 14:42
但如果T2是对同一行做update操作,就会等待。如果表A是myisam引擎就不会出现等待。
作者:
devilkin0312
时间:
2012-04-12 18:35
学习了
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2