Mysql InnoDB 事务模式与锁定
2008-07-18 10:55
441 查看
在InnoDB的行锁中使用所谓的next-keylocking。这就意味着,除了索引记录外,InnoDB还可以锁定该索引记录前部“间隙”('gap')以阻塞其它用户在索引记录前部的直接插入。next-keylock意思是锁定一个索引记录以及该记录之前的间隙(gap)。gaplock就是只锁定某些索引记录之前的间隙。
Consistentread
Consistentread就是InnoDB使用它的多版本(multiversioning)方式提供给查询一个数据库在一个时间点的快照。查询将会检查那些在这个时间点之前提交的事务所做的改动,以及在时间点之后改变或未提交的事务?与这个规则相例外的是查询将检查查询自身发出的事务所做的改变。
如果以默认的
Consistentread在InnoDB处理
Lockingreads
Consistentread在某些情况下是不太方便的。假设你希望在表
假设你使用consistentread了读取表
解决的办法就是在锁定的方式
在共享模式下执行读取的意思就是读取最新的现有资料,并在所读取的行上设置一个共享模式的锁定。如果最新的数据属于其它用户仍未提交的事务,那将不得不等到这个事务被提交。共享模式的可以防止其它用户更新或删除我们当前所读取的行。当查询获得
另外一个例子:在表
在这和情况下有两种方法来实现读取并增加计数器:(1)首先更新计数器然后再读取它;(2)首先以一个
引自:http://imysql.cn/docs/innodb/8.htm
Consistentread
Consistentread就是InnoDB使用它的多版本(multiversioning)方式提供给查询一个数据库在一个时间点的快照。查询将会检查那些在这个时间点之前提交的事务所做的改动,以及在时间点之后改变或未提交的事务?与这个规则相例外的是查询将检查查询自身发出的事务所做的改变。
如果以默认的
REPEATABLEREAD隔离级,那么所有在同一事务中的consistentreads只读取同一个在事务中第一次读所确定的快照。你可以通过提交当前事务并发出一个新的查询以获得新的数据快照。
Consistentread在InnoDB处理
SELECT中的默认模式是
READCOMMITTED和
REPEATABLEREAD隔离级。Consistentread对其所访问的表不加任何锁定,因而其它任何用户均可以修改在consistentread被完成之前自由的修改这些表。
Lockingreads
Consistentread在某些情况下是不太方便的。假设你希望在表
CHILD中插入一个新行,而这个子表已有一个父表
PARENT。
假设你使用consistentread了读取表
PARENT并查看子表中对应记录。你真的能安全地在表
CHILD中加入一个子行?不可能,因为在此期间可能有其它用户删除了表
PARENT中的父行,而你并不知道它。
解决的办法就是在锁定的方式
LOCKINSHAREMODE下运行一个
SELECT。
在共享模式下执行读取的意思就是读取最新的现有资料,并在所读取的行上设置一个共享模式的锁定。如果最新的数据属于其它用户仍未提交的事务,那将不得不等到这个事务被提交。共享模式的可以防止其它用户更新或删除我们当前所读取的行。当查询获得
'Jones'后,就可以安全地向子表
CHILD中加入子行,然后提交事务。这个例子显示如何在应用程序代码中实现参照完整性。
另外一个例子:在表
CHILD_CODES有一个整型计数字段用于给在表
CHILD中加入的每个子行赋于一个唯一的标识符。显而易见地,用一个consistentread来读取父表中的值并不是一个好的主意,因两个用户有可能会读取出同一个计数值,当以同一个标识符插入两个字行时将会产生一个重复键值(duplicatekey)的错误。如果两个用户同时读取了计数器,当尝试更新计数器时,他们中的一个必将在死锁中结束,所以在读取时使用
LOCKINSHAREMODE也并不是一个好的解决办法。
在这和情况下有两种方法来实现读取并增加计数器:(1)首先更新计数器然后再读取它;(2)首先以一个
FORUPDATE方式锁定后再读取,然后再增加它:
READUNCOMMITTED这通常称为'dirtyread':non-locking
SELECTs的执行使我们不会看到一个记录的可能更早的版本;因而在这个隔离度下是非'consistent'reads;另外,这级隔离的运作如同
READCOMMITTED。
READCOMMITTED有些类似Oracle的隔离级。所有
SELECT...FORUPDATE和
SELECT...LOCKINSHAREMODE语句只锁定索引记录,而不锁定之前的间隙,因而允许在锁定的记录后自由地插入新记录。以一个唯一地搜索条件使用一个唯一索引(uniqueindex)的
UPDATE和
DELETE,仅仅只锁定所找到的索引记录,而不锁定该索引之前的间隙。但是在范围型的
UPDATEand
DELETE中,InnoDB必须设置next-key或gaplocks来阻塞其它用户对范围内的空隙插入。自从为了MySQL进行复制(replication)与恢复(recovery)工作'phantomrows'必须被阻塞以来,这就是必须的了。Consistentreads运作方式与Oracle有点类似:每一个consistentread,甚至是同一个事务中的,均设置并作用它自己的最新快照。
REPEATABLEREAD这是InnoDB默认的事务隔离级。.
SELECT...FORUPDATE,
SELECT...LOCKINSHAREMODE,
UPDATE,和
DELETE,这些以唯一条件搜索唯一索引的,只锁定所找到的索引记录,而不锁定该索引之前的间隙。否则这些操作将使用next-key锁定,以next-key和gaplocks锁定找到的索引范围,并阻塞其它用户的新建插入。在consistentreads中,与前一个隔离级相比这是一个重要的差别:在这一级中,同一事务中所有的consistentreads均读取第一次读取时已确定的快照。这个约定就意味着如果在同一事务中发出几个无格式(plain)的
SELECTs,这些
SELECTs的相互关系是一致的。
SERIALIZABLE这一级与上一级相似,只是无格式(plain)的
SELECTs被隐含地转换为
SELECT...LOCKINSHAREMODE。
引自:http://imysql.cn/docs/innodb/8.htm
相关文章推荐
- Mysql InnoDB中的查询事务模式与锁定select ..for update
- Mysql InnoDB中的查询事务模式与锁定select ..for update
- InnoDB中文参考手册---8InnoDB事务模式与锁定
- InnoDB 中文参考手册 --- 8 InnoDB 事务模式与锁定
- MySQL Innodb事务编程问题和处理
- MySQL事务与锁定命令
- MySQL InnoDB之事务与锁详解
- javaweb(三十八)——mysql事务和锁InnoDB(扩展)
- PHP 处理 MySQL INNODB 事务回滚(ThinkPHP、MySQL、PDO)
- MySQL InnoDB四个事务级别 与 脏读、不重复读、幻读
- MySQL InnoDB之事务与锁详解
- mysql 开发基础系列20 事务控制和锁定语句(上)
- mysql 开发基础系列21 事务控制和锁定语句(下)
- 7 MySQL 事务与锁定命令
- mysql的innodb中事务日志ib_logfile
- MySQL的InnoDB事务
- mysql事务和锁InnoDB
- Mysql-InnoDB 事务-一致性读(快照读)
- MySQL GTID模式 主从复制跳过错误事务
- mysql事务和锁InnoDB