转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 数据库 >> SyBase >> 正文
InnoDB 中文参考手册 --- 8 InnoDB 事务模式与锁定         ★★★★

InnoDB 中文参考手册 --- 8 InnoDB 事务模式与锁定

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1445 更新时间:2009/4/22 23:09:06
SERIALIZABLE,在这种情况下将在它所读取的记录索引上设置共享的 next-key locks。
  • SELECT ... FROM ... LOCK IN SHARE MODE : 在所读取的所有记录索引上设置同享的锁定。
  • SELECT ... FROM ... FOR UPDATE : 在所读取的所胡记录索引上设置独占地(exclusive)锁定。
  • INSERT INTO ... VALUES (...) : 在插入的记录行上设置一个独占地锁定;注意这个锁定并不是一个 next-key lock ,并不会阻止其它用户在所插入行之前的间隙(gap)中插入新记录。如果产生一个重复键值错误, 在重复索引记录上设置一个共享的锁定。
  • 如果在一个表中定义了一个 AUTO_INCREMENT 列,InnoDB 在初始化自增计数器时将在与自增列最后一个记录相对应的索引上设置一个独占的锁定。在访问自增计数器时, InnoDB 将设置一个特殊的表锁定模式 AUTO-INC ,这个锁定只持续到该 SQL 语句的结束而不是整个事务的结束。
  • INSERT INTO T SELECT ... FROM S WHERE ... 在已插入到表 T 中的每个记录上设置一个独占的(无 next-key)锁定。以一个 consistent read 搜索表 S ,但是如果 MySQL 打开了日志开关将在表 S 上设置一个共享的锁定。 在从备份中进行前滚(roll-forward)修复时,每个 SQL 语句必须严格按照原先所执行的顺序运行,所以 InnoDB 不得不设置锁定。
  • CREATE TABLE ... SELECT ... 与上项相似,以 consistent read 或锁定方式完成 SELECT
  • REPLACE 如果没有一个 unique key 冲突,它的执行与 insert 一致。否则将在它所要更新的记录上设置一个独占的锁定。
  • UPDATE ... SET ... WHERE ... : 在搜索时所遭遇到的记录上设置一个独占的锁定。
  • DELETE FROM ... WHERE ... : 在搜索时所遭遇到的每一个记录上设置一个独占的锁定。
  • 如果一个表上有 FOREIGN KEY 约束,所有需要检查约束条件的 insert, update, 或 delete 将在它所要检查约束的记录上设置记录共享级的锁定。同样在约束失败时,InnoDB 也设置这个锁定。
  • LOCK TABLES ... : 设置表锁定。在 MySQL 的代码层(layer of code)设置这些锁定。InnoDB 的自动死锁检测无法检测出有关下列情形的表锁定:查看下面的一个章节。同时查看第 14 章节 ''''InnoDB 限制与不足'''' 有关下列内容: 自从 MySQL 提供行锁以来,将有可能发生当其他用户设置了行级锁定时你又对该表设置了锁定。But that does not put transaction integerity into danger.
  • 在 3.23.50 版本以前, SHOW TABLE STATUS 应用于一个自增表时将在自增列的最大记录索引上设置一个独占的行级锁定。 这就意味着 SHOW TABLE STATUS 可能会引起一个事务的死锁,这可能是我们所意想不到的。从 3.23.50 开始,在读取自增列值时将不再设置任何锁定,除非在某些情况下,比如在数据库启动后没有任何记录。
  • 8.5 MySQL 什么时候隐含地提交(commit)或回滚(rollback)事务?

    • 如果你不使用 SET AUTOCOMMIT=0,MySQL 将会在一个会话中打开自动提交模式。在自动提交模式下,如果一条 SQL 语句没有返回任何错误,MySQL 将在这条 SQL 语句后立即提交。
    • 如果一条 SQL 语句返回一个错误,那么 commit/rollback 依赖于这个错误。查看第国家13 章节详细描述。
    • 下列的 SQL 语句在 MySQL 引起中当前事务的隐含提交:CREATE TABLE (如果使用了 MySQL 二进制日志''''binlogging''''), ALTER TABLE, BEGIN, CREATE INDEX, DROP DATABASE, DROP TABLE, RENAME TABLE, TRUNCATE, LOCK TABLES, UNLOCK TABLES。 在 InnoDB 中 CREATE TABLE 语句是作为一个单独的事务来处理的。这就意味着一个用户无法在他的事务中使用 ROLLBACK 撤销 CREATE TABLE 语句操作。
    • 如果你关闭了自动提交模式,而在关闭一个连接之前又未使用 COMMIT 提交你的事务,那么 MySQL 将回滚你的事务。

    8.6 死锁检测与回滚

    InnoDB 会自动检测一个事务的死锁并回滚一个或多个事务来防止死锁。从 4.0.5 版开始,InnoDB 将设法提取小的事务来进行回滚。一个事务的大小由它所插入(insert)、更新(update)和删除(delete)的数据行数决定。 Previous to 4.0.5, InnoDB always rolled back the transaction whose lock request was the last one to build a deadlock, that is, a cycle in the waits-for graph of transactions.

    InnoDB 不能检测出由 MySQL 的 LOCK TABLES 语句引起的死锁,或其它的表类型中的锁定所引起的死锁。你不得不通过在 my.cnf 中设置 innodb_lock_wait_timeout 参数来解决这些情形。

    当 InnoDB 执行一个事务完整的回滚,这个事务所有所加的锁将被释放。然而,如果只一句的 SQL 语句因结果返回错误而进行回滚的,由这条 SQL 语句所设置的锁定可能会被保持。这是因为 InnoDB r的行锁存储格式无法知道锁定是由哪个 SQL 语句所设置。

    8.7 consistent read 在 InnoDB 运作示例

    假设你以默认的 REPEATABLE READ 事务隔离级水平运行。当你发出一个 consistent read 时,即一个普通的 SELECT 语句,InnoDB 将依照你的查询检查数据库给你的事务一个时间点(timepoint)。因而,如果事务 B 在给你指定的时间点后删除了一行并提交,那么你并不能知道这一行已被删除。插入(insert)与更新(update)也是一致的。

    你可以通过提交你的事务并重新发出一个 SELECT 来将你的时间点提前。

    这就叫做 multiversioned 并发控制。

    
    time
      |
      |
      |
      |
      | 
      v 
    User A
    User B
    set autocommit=0;   
    set autocommit=0;
    SELECT * FROM t;
    empty set
       
    INSERT INTO t VALUES (1, 2);
    SELECT * FROM t;
    empty set
       
    COMMIT;
    SELECT * FROM t; 
    empty set;
    COMMIT;
    SELECT * FROM t;
    ---------------------
    | 1 | 2 |
    ---------------------
      因而,只有当用户 B 提交了他的插入,并且用户 A 也提交了他的事务从而使时间点越过 B 提交时的时间点之后,用户 A 才能看到用户 B 所插入的新行。

    如果你希望查看数据库“最新的(freshest)”状态,你必须使用 READ COMMITTED 事务隔离级,或者你可以使用读锁:

    SELECT * FROM t LOCK IN SHARE MODE;
     

     

    8.8 如何应付死锁?

    死锁是事务处理型数据库系统的一个经典问题,但是它们并不是很危险的, 除非它们如此地频繁以至于你根本处理不了几个事务。 当因死锁而产生了回滚时,你通常可以在你的应用程序中重新发出一个事务即可。

    InnoDB 使用自动地行级锁定。你可能恰好在插入或删除单一一条记录时产生死锁。 这是因为这些操作并不是真正“原子(atomic)”级的:他们会自动地在锁定 inserted/deleted 行的索引记录(可能有几个)。

    可以通过下面所示的技巧来应付死锁或减少死锁的次数:

    • 在 MySQL >=3.23.52 和 >= 4.0.3 的版本中使用 SHOW INNODB STATUS 来确定引起最后一个死锁的原因。这可以帮助你调整你的应用程序来避免死锁。
    • 总是准备在因死锁而发生错误时重新发出一个事务。死锁并不危险。仅仅只需重试一遍。
    • 经常提交你的事务。小的事务有较少的碰撞可能。
    • 如果使用锁定读取 SELECT ... FOR UPDATE... LOCK IN SHARE MODE,尽量使用较低的隔离级 READ COMMITTED
    • 以一个固定秩序(a fixed order)访问你的表和记录。这样事务将形成一个较精细的队列,而避免死锁。
    • 为你的表添加合适的索引。那么你的查询只需要扫描较少的索引,因而设置较少的锁定。使用 EXPLAIN SELECT 来确定 MySQL 为你的查询挑选的适当的索引。
    • 尽量少用锁定:如果可以通过一个 SELECT 在一个较老的数据快照中获得所需数据,就不要再添加子句 FOR UPDATELOCK IN SHARE MODE 。在这时使用 READ COMMITTED 隔离级是较好的主意,因为在同一个事务中的每个 consistent read 只读取它最先确定的数据快照。
    • 如果仍然没有什么补救效果,使用表级锁定连载你的事务(serialize transactions):LOCK TABLES t1 WRITE, t2 READ, ... ; [do something with tables t1 and t2 here]; UNLOCK TABLES。表级锁定可以使你的事务形成精细的队列。注意 LOCK TABLES 隐含地启动一个事务,就如同命令 BEGINUNLOCK TABLES 如同 COMMIT 一样隐含地结束一个事务。
    • 连载事务(serialize transactions)的另一个解决办法就是建立一个仅有一行记录的辅助“信号量(semaphore)” 表。每一个事务在访问其它表之前均更新这个记录。通过这种方式所有的事务将持续执行。注意同时 InnoDB 实时死锁检测算法也在工作着,因为这个持续锁定(serializing lock)是一个行锁定。在 MySQL 中对于表级锁定我们必须采取超时方式。

     

    上一页  [1] [2] 


    [办公软件]用Ctrl+Shift+8快速选择Excel连续的块状数据  [聊天工具]Windows Live Messenger 8 Beta1高清图赏__天极Ye…
    [聊天工具]MSN Messenger 8 Beta简单试用报告__天极Yesky  [聊天工具]Windows Live Messenger 8 截图欣赏__天极Yesky
    [聊天工具]MSN Messenger8 超酷头像任你选__天极Yesky  [常用软件]painter 8 菜单中英文对照
    [VB.NET程序]VB.NET实现DirectSound9 (8) 音效控制器  [VB.NET程序]几个 WMI 的例子(初级) - 1
    [VB.NET程序]几个 WMI 的例子(初级) - 2  [VB.NET程序]几个 WMI 的例子(初级) - 3
    教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · Sql Server  · MySql
    · Access  · ORACLE
    · SyBase  · 其他
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台