add by zhj: 看来我对MySQL的理解还有待深入,水还是挺深的啊,MySQL给记录加锁时,可以通过innodb_lock_wait_timeout参数设置超时时间,

如果加锁等待超过这个时间,就会回滚,但回滚的话有两种方式:第一种:回滚当前加锁的这条语句;第二种:回滚整个事务。这两种方式是通过参数

innodb_rollback_on_timeout来控制的。如果是OFF,表示加锁超时回滚时,只回滚加锁超时的那条SQL语句;如果是ON,表示回滚整个事务。默认

是OFF。在《MySQL Admin Cookbook》一书中,作者强烈建议该参数设置为ON,但其实OFF也没关系,你可以在应用程序中捕获那个加锁超时,然

后应用程序去执行ROLLBACK,这样就可以保证原子性,只要你没执行COMMIT,就不会破坏原子性。Django应该就是这么做的。我个人拙见是:感觉

设置为ON,依靠数据库本身自动完成回滚更好一些。

原文:http://www.cnblogs.com/hustcat/archive/2012/11/18/2775487.html

1、innodb_rollback_on_timeout变量

下面是MySQL官方手册关开innodb_rollback_on_timeout变量的说明:

In MySQL 5.0.13 and up, InnoDB rolls back only the last statement on a transaction timeout by default. If --innodb_rollback_on_timeout is specified, a transaction timeout causes InnoDB to abort and roll back the entire transaction (the same behavior as before MySQL 5.0.13). This variable was added in MySQL 5.0.32.

该变量默认值为OFF,如果事务因为加锁超时,会回滚上一条语句执行的操作。如果设置ON,则整个事务都会回滚。

下面通过一个示例来验证上面这段话。

2、示例

(1) innodb_rollback_on_timeout为OFF

Session 1

Session 2

mysql> create table tt(c1 int primary key, c2 int)engine=innodb;

Query OK, 0 rows affected (0.01 sec)

mysql> insert into tt values(1, 1);

Query OK, 1 row affected (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tt where c1=1 lock in share mode;

+----+------+

| c1 | c2   |

+----+------+

|  1 |    1 |

+----+------+

1 row in set (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into tt values(10,10);

Query OK, 1 row affected (0.00 sec)

mysql> delete from tt where c1=1;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

mysql> select * from tt;

+----+------+

| c1 | c2   |

+----+------+

|  1 |    1 |

| 10 |   10 |

+----+------+

2 rows in set (0.00 sec)

mysql> rollback;

Query OK, 0 rows affected (0.01 sec)

mysql> select * from tt;

+----+------+

| c1 | c2   |

+----+------+

|  1 |    1 |

+----+------+

1 row in set (0.00 sec)

mysql> select * from tt;

+----+------+

| c1 | c2   |

+----+------+

|  1 |    1 |

+----+------+

1 row in set (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into tt values(10,10);

Query OK, 1 row affected (0.00 sec)

mysql> delete from tt where c1=1;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

mysql> commit;

Query OK, 0 rows affected (0.02 sec)

mysql> select * from tt;

+----+------+

| c1 | c2   |

+----+------+

|  1 |    1 |

| 10 |   10 |

+----+------+

2 rows in set (0.00 sec)

session2因为加锁超时,事务回退到上一条语句。

(2) innodb_rollback_on_timeout为ON

Session 1

Session 2

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tt where c1=1 lock in share mode;

+----+------+

| c1 | c2   |

+----+------+

|  1 |    1 |

+----+------+

1 row in set (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into tt values(11,11);

Query OK, 1 row affected (0.00 sec)

mysql> delete from tt where c1=1;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

mysql> select * from tt;

+----+------+

| c1 | c2   |

+----+------+

|  1 |    1 |

| 10 |   10 |

+----+------+

2 rows in set (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tt;

+----+------+

| c1 | c2   |

+----+------+

|  1 |    1 |

| 10 |   10 |

+----+------+

2 rows in set (0.00 sec)

session2加锁超时,整个事务回滚。

3、总结

innodb_rollback_on_timeout为OFF,事务会回滚到上一个保存点,InnoDB在执行每条SQL语句之前,都会创建一个保存点,参见代码:

int

row_insert_for_mysql(

                                               /* out: error code or DB_SUCCESS */

         byte*                 mysql_rec,       /* in: row in the MySQL format */

         row_prebuilt_t*     prebuilt)  /* in: prebuilt struct in MySQL

                                               handle */

{

。。。

         savept = trx_savept_take(trx);

。。。

如果事务因为加锁超时,相当于回滚到上一条语句。但是报错后,事务还没有完成,用户可以选择是继续提交,或者回滚之前的操作,由用户选择是否进一步提交或者回滚事务。

innodb_rollback_on_timeout为ON,整个事务都会回滚。这可以从row_mysql_handle_errors函数中得到验证。

 
ibool
row_mysql_handle_errors(
/*====================*/
                /* out: TRUE if it was a lock wait and
                we should continue running the query thread */
    ulint*        new_err,/* out: possible new error encountered in
                lock wait, or if no new error, the value
                of trx->error_state at the entry of this
                function */
    trx_t*        trx,    /* in: transaction */
    que_thr_t*    thr,    /* in: query thread */
    trx_savept_t*    savept)    /* in: savepoint or NULL */
{
...
else if (err == DB_DEADLOCK //发生死锁
           || err == DB_LOCK_TABLE_FULL
           || (err == DB_LOCK_WAIT_TIMEOUT
               && row_rollback_on_timeout)) {
        /* Roll back the whole transaction; this resolution was added
        to version 3.23.43 */         trx_general_rollback_for_mysql(trx, FALSE, NULL); //事务全部回滚
                
    } else if (err == DB_OUT_OF_FILE_SPACE
           || err == DB_LOCK_WAIT_TIMEOUT) {         ut_ad(!(err == DB_LOCK_WAIT_TIMEOUT
                && row_rollback_on_timeout));                if (savept) { //回滚到上一个保存点
            /* Roll back the latest, possibly incomplete
            insertion or update */             trx_general_rollback_for_mysql(trx, TRUE, savept);
        }
        /* MySQL will roll back the latest SQL statement */
...
 

问题:innodb_rollback_on_timeout为OFF,事务的原子性被破坏了吗?

答:NO,从示例中可以看到,事务只是回退上一条语句的状态,而整个事务实际上没有完成(提交或者回滚),而作为应用程序在检测这个错误时,应该选择是提交或者回滚事务。如果严格要求事务的原子性,当然是执行ROLLBACK,回滚事务。

MySQL InnoDB加锁超时回滚机制(转)的更多相关文章

  1. mysql事务提交和回滚机制

    应用场景:   银行取钱,从ATM机取钱,分为以下几个步骤       1 登陆ATM机,输入密码:    2 连接数据库,验证密码:    3 验证成功,获得用户信息,比如存款余额等:    4 用 ...

  2. Hadoop HDFS概念学习系列之HDFS升级和回滚机制(十二)

    不多说,直接上干货! HDFS升级和回滚机制 作为一个大型的分布式系统,Hadoop内部实现了一套升级机制,当在一个集群上升级Hadoop时,像其他的软件升级一样,可能会有新的bug或一些会影响现有应 ...

  3. spring boot开启事务管理,使用事务的回滚机制,使两条插入语句一致

    spring boot 事务管理,使用事务的回滚机制 1:配置事务管理 在springboot 启动类中添加 @EnableTransactionManagement //开启事务管理 @Enable ...

  4. oracle回滚机制深入研究

    这篇文章主要描写叙述oracle的回滚机制,篇幅可能较长,由于对于oracle的回滚机制来说,要讨论和描写叙述的实在太多,仅仅能刷选自己觉得最有意义的一部分进行深入研究和分享 一.我们来看一个DML语 ...

  5. 关于MySQL回滚机制

    在事务中,每个正确的原子操作都会被顺序执行,直到遇到错误的原子操作,此时事务会将之前的操作进行回滚.回滚的意思是如果之前是插入操作,那么会执行删 除插入的记录,如果之前是update操作,也会执行up ...

  6. mysql事务回滚机制概述

    应用场景:   银行取钱,从ATM机取钱,分为以下几个步骤       1 登陆ATM机,输入密码:    2 连接数据库,验证密码:    3 验证成功,获得用户信息,比如存款余额等:    4 用 ...

  7. Spring中的事务回滚机制

    初学者笔记 问题:在Java项目汇中,添加@Transactional注解,报错之后,事务回滚未生效,数据仍插入数据库中.经查看报错位置位于新增成功之后.空指针异常. 一.特性 先了解一下@Trans ...

  8. 【MySQL】使用mysqlbinlog回滚

    参考:http://wubx.net/?s=mysqlbinlog mysql官方的mysqlbinlog没有回滚的功能,淘宝大牛对官方代码进行了修改使之能够将binlog中的DML操作变成互逆的语句 ...

  9. 对mysql事务提交、回滚的错误理解

    一.起因 begin或者START TRANSACTION开始一个事务 rollback事务回滚 commit 事务确认 人们对事务的解释如下:事务由作为一个单独单元的一个或多个SQL语句组成,如果其 ...

随机推荐

  1. 关于Unity中NGUI的Pivot和锚点

    Pivot 1.创建一个Sprite类型的Sprite1节点,关联一个图集和一张贴图,用图中的六个按钮调整这个贴图的Pivot点,一共有八个点可以选择 2.再创建一个Sprite类型的Sprite2节 ...

  2. windows下更换pip源

    (1)在windows文件管理器中,输入 %APPDATA% (2)会定位到一个新的目录下,在该目录下新建pip文件夹,然后到pip文件夹里面去新建个pip.ini文件 (3)在新建的pip.ini文 ...

  3. shell脚本中的逻辑判断 文件目录属性判断 if特殊用法 case判断

    case判断 • 格式 case  变量名 in                       value1)                           command            ...

  4. Dapper的基本使用,Insert、Update、Select、Delete

    简介 Dapper是.NET下一个micro的ORM,它和Entity Framework或Nhibnate不同,属于轻量级的,并且是半自动的.也就是说实体类都要自己写.它没有复杂的配置文件,一个单文 ...

  5. asp.net Ajax调用Aspx后台方法

    Ajax调用的前提(以aspx文件为例:) 1.首先需要在aspx文件后台中引用using System.Web.Services; 2.需要调用的方法必须是公共的(public).静态的(stati ...

  6. MySQL介绍,下载,安装,配置

    MySQL用了很多年了,今天写个总结. 一.介绍 MySQL是开源软件,后来归Oracle所有.开源便于软件的完善改进.但开源不等于滥用,也不等于完全免费.MySQL有商业版,商业用途是付费的.也有免 ...

  7. 洛谷 P1208混合牛奶【贪心】

    题目描述 由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要.帮助Marry乳业找到最优的牛奶采购方案. Marry乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格是 ...

  8. Sql Server :SELECT a.*,b.HZXM FROM YG_LIS_JCBYTK a(nolock)中的NOLOCK作用

    转自 http://blog.csdn.net/xingxing1828/article/details/34850771 先说下其区别,之后再做测试. 大家都知道,每新建一个查询,都相当于创建一个会 ...

  9. {python之协程}一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二

    python之协程 阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本 ...

  10. 使用FFmpeg常见问题

    使用FFmpeg常见问题 https://blog.csdn.net/willib/article/details/52530328 https://blog.csdn.net/nogodoss/ar ...