innodb隔离级别和加锁机制

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

测试原因:理解“一致性的非锁定读”操作及相关锁机制。1.在Readcommitted事务隔离级别下,对于快照数据,“一致性的非锁定读”总是读取被锁定行的最新一份快照数据。2.在Repeatableread事务隔离级别下,对于快照数据,“一致性的非锁定读”总是读取事务开始时的行数据版本。测试条件:在一行进行delete、update操作时,读操作不会等待该行锁的释放,而会读取一个快照版本。测试涉及的知识:隔离级别读数据一致性脏读不可重复读幻读未提交读(Readuncommitted)最低级别,只能保证不读取物理上损坏的数据是是是已提交度(Readcommitted)语句级否是是可重复读(Repeatableread)事务级否否是可序列化(Serializable)最高级别,事务级否否否锁类型共享锁(SLock),允许事务读一行数据排他锁(XLock),允许事务删除或者更新一行数据意向锁(表级别)意向共享锁(ISLock),事务想要获得一个表中某几行的共享锁意向排他锁(IXLock),事务想要获得一个表中某几行的排他锁对读操作进行加锁select...forupdate加x锁,可以防止丢失更新的问题select...lockinsharemode(在Serializable事务级别下,每条select语句,自动加上lockinsharemode)加s锁锁算法recordlock单个行记录上的锁gaplock间隙锁,锁定一个范围,但不锁定记录本身next-keylock锁定一个范围,并且锁定记录本身(在Repeatableread事务级别下,使用该算法,可避免幻读的产生。)多版本并发控制,MVCC注意:在MySQL5.5中,我尝试动态更改tx_isolation,结果报错,该参数不能更改。修改my.cnf,重启服务。测试环境:MySQL5.5创建一个测试表createtablet(aintnotnullprimarykey,bvarchar(100));insertintotselect1,'abc';测试过程1.READ-COMMITTED隔离级别mysqlshowglobalvariableslike'tx_isolation';+---------------+----------------+|Variable_name|Value|+---------------+----------------+|tx_isolation|READ-COMMITTED|+---------------+----------------+1rowinset(0.00sec)session1session2mysqlbegin;QueryOK,0rowsaffected(0.00sec)mysqlselect*fromtwherea=1;+---+------+|a|b|+---+------+|1|abc|+---+------+1rowinset(0.00sec)开始一个事务,并读取a=1这行的记录。mysqlbegin;QueryOK,0rowsaffected(0.00sec)mysqlupdatetseta=2wherea=1;QueryOK,1rowaffected(0.00sec)Rowsmatched:1Changed:1Warnings:0同样开始一个事务,并更改a=1这样的记录,先不提交。a=1这一行就获得了一个X锁。mysqlselect*fromtwherea=1;+---+------+|a|b|+---+------+|1|abc|+---+------+1rowinset(0.00sec)再次查询,可以查询,但是记录是未改变的。分析:“一致性的非锁定读”总是读取被锁定行的最新一份快照数据。mysqlcommit;QueryOK,0rowsaffected(0.01sec)mysqlselect*fromtwherea=1;Emptyset(0.00sec)测试数据还原mysqlupdatetseta=1wherea=2;QueryOK,1rowaffected(0.01sec)Rowsmatched:1Changed:1Warnings:02.Repeatablereadmysqlshowglobalvariableslike'tx_isolation';+---------------+-----------------+|Variable_name|Value|+---------------+-----------------+|tx_isolation|REPEATABLE-READ|+---------------+-----------------+1rowinset(0.00sec)ssession1session2mysqlbegin;QueryOK,0rowsaffected(0.00sec)mysqlselect*fromtwherea=1;+---+------+|a|b|+---+------+|1|abc|+---+------+1rowinset(0.00sec)开始一个事务,并读取a=1这行的记录。mysqlbegin;QueryOK,0rowsaffected(0.00sec)mysqlupdatetseta=2wherea=1;QueryOK,1rowaffected(0.00sec)Rowsmatched:1Changed:1Warnings:0同样开始一个事务,并更改a=1这样的记录,先不提交。a=1这一行就获得了一个X锁。mysqlselect*fromtwherea=1;+---+------+|a|b|+---+------+|1|abc|+---+------+1rowinset(0.00sec)再次查询,可以查询,但是记录是未改变的。mysqlcommit;QueryOK,0rowsaffected(0.01sec)mysqlselect*fromtwherea=1;+---+------+|a|b|+---+------+|1|abc|+---+------+mysqlselect*fromtwherea=1;Emptyset(0.00sec)读取不到数据是理所当然的。1rowinset(0.00sec)session2提交了事务,但是这里读取的记录仍然未改变分析:“一致性的非锁定读”总是读取本次事务开始时的行数据版本。四种隔离级别带来的脏读、不重复、可重复、幻影数据的讲解MySQLInnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLEREAD)。·未提交读(READUNCOMMITTED)。另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据(脏读)。·提交读(READCOMMITTED)。本事务读取到的是最新的数据(其他事务提交后的)。问题是,在同一个事务里,前后两次相同的SELECT会读到不同的结果(不重复读)。·可重复读(REPEATABLEREAD)。在同一个事务里,SELECT的结果是事务开始时时间点的状态,因此,同样的SELECT操作读到的结果会是一致的。但是,会有幻读现象(稍后解释)。·串行化(SERIALIZABLE)。读操作会隐式获取共享锁,可以保证不同事务间的互斥。四个级别逐渐增强,每个级别解决一个问题。·脏读,最容易理解。另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据。·不重复读。解决了脏读后,会遇到,同一个事务执行过程中,另外一个事务提交了新数据,因此本事务先后两次读到的数据结果会不一致。·幻读。解决了不重复读,保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。但是,如果另一个事务同时提交了新数据,本事务再更新时,就会“惊奇的”发现了这些新数据,貌似之前读到的数据是“鬼影”一样的幻觉。

1 / 5
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功