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. 【转】WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: 日历控件Calendar自定义样式: 日期控件DatePicker自定 ...

  2. perl _DATA_ 文件句柄

    常用的perl 读写文件的操作,我们都很熟悉了,需要先声明1个文件句柄.但是看下面这段代码: my %organisms = (); while(<DATA>){ chomp; if(/^ ...

  3. 关于tomcat7服务下面js无法获取JSESSIONID的cookie信息

    http://tomcat.apache.org/tomcat-5.5-doc/config/context.html Does anyone know what changed in the con ...

  4. Keepalived 配置高可用集群

    一.Keepalived 简介 (1) Keepalived 能实现高可用也能实现负载均衡,Keepalived 是通过 VRRP 协议 ( Virtual Router Redundancy Pro ...

  5. Android打印当前所有线程及对应栈信息

    Map<Thread, StackTraceElement[]> threadMap = Thread.getAllStackTraces(); Log.e("albertThr ...

  6. Android Selinux

    https://blog.csdn.net/rikeyone/article/details/84337115   如何快速定位SElinux问题并修复? https://blog.csdn.net/ ...

  7. iOS - 标准时间与时间戳相互转换

    做倒计时后台传的不是时间戳,是时间然后需要与系统时间对比得出时间戳进行倒计时显示 #pragma mark -- 倒计时 // 倒计时时间 NSString* timeStr = task.recei ...

  8. PHP数组总结,,PHP面向对象思维思路。

    <?php //定义数组 $attr = array(); $attr[] = ; //索引数组 $attr = array(,,,); //关联数组 $attr = array("c ...

  9. datagrid--新增

    先在datagrid中添加toolbar配置项,增删改差的按钮,有3个属性,按钮名称,图标,回调函数,点击按钮会弹出一个对话框dialog,dialog是关闭的,closed=true, toolba ...

  10. VC++、Win32 SDK、MFC的区别

    这是一个初进行开发人员都可能遇到过的概念不清的问题,自己当年也同样有过误解,做技术我感觉一定要专,但是,不代表毫不关心相关的知识,至少概念层次上要知道,所以,这里还是再把这些内容纪录下来,好记性不如烂 ...