MySQL InnoDB加锁超时回滚机制(转)
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加锁超时回滚机制(转)的更多相关文章
- mysql事务提交和回滚机制
应用场景: 银行取钱,从ATM机取钱,分为以下几个步骤 1 登陆ATM机,输入密码: 2 连接数据库,验证密码: 3 验证成功,获得用户信息,比如存款余额等: 4 用 ...
- Hadoop HDFS概念学习系列之HDFS升级和回滚机制(十二)
不多说,直接上干货! HDFS升级和回滚机制 作为一个大型的分布式系统,Hadoop内部实现了一套升级机制,当在一个集群上升级Hadoop时,像其他的软件升级一样,可能会有新的bug或一些会影响现有应 ...
- spring boot开启事务管理,使用事务的回滚机制,使两条插入语句一致
spring boot 事务管理,使用事务的回滚机制 1:配置事务管理 在springboot 启动类中添加 @EnableTransactionManagement //开启事务管理 @Enable ...
- oracle回滚机制深入研究
这篇文章主要描写叙述oracle的回滚机制,篇幅可能较长,由于对于oracle的回滚机制来说,要讨论和描写叙述的实在太多,仅仅能刷选自己觉得最有意义的一部分进行深入研究和分享 一.我们来看一个DML语 ...
- 关于MySQL回滚机制
在事务中,每个正确的原子操作都会被顺序执行,直到遇到错误的原子操作,此时事务会将之前的操作进行回滚.回滚的意思是如果之前是插入操作,那么会执行删 除插入的记录,如果之前是update操作,也会执行up ...
- mysql事务回滚机制概述
应用场景: 银行取钱,从ATM机取钱,分为以下几个步骤 1 登陆ATM机,输入密码: 2 连接数据库,验证密码: 3 验证成功,获得用户信息,比如存款余额等: 4 用 ...
- Spring中的事务回滚机制
初学者笔记 问题:在Java项目汇中,添加@Transactional注解,报错之后,事务回滚未生效,数据仍插入数据库中.经查看报错位置位于新增成功之后.空指针异常. 一.特性 先了解一下@Trans ...
- 【MySQL】使用mysqlbinlog回滚
参考:http://wubx.net/?s=mysqlbinlog mysql官方的mysqlbinlog没有回滚的功能,淘宝大牛对官方代码进行了修改使之能够将binlog中的DML操作变成互逆的语句 ...
- 对mysql事务提交、回滚的错误理解
一.起因 begin或者START TRANSACTION开始一个事务 rollback事务回滚 commit 事务确认 人们对事务的解释如下:事务由作为一个单独单元的一个或多个SQL语句组成,如果其 ...
随机推荐
- Redis数据库高级实用特性:持久化机制
Redis数据库高级实用特性:持久化机制 大型web系统数据缓存设计 Redis高级特性:虚拟内存的使用技巧 Redis高级实用特性:安全性与主从复制 Memcached.Redis OR Tair
- 原生JS封装ajax方法
http://blog.sucaijiayuan.com/article/89 jquery框架的ajax方法固然好用,但是假如某天我们的项目不能引入jquery或项目需求很简单,没有很多交互功能,只 ...
- 硬件信息 dmidecode dmesg lsdev lshw haparm lsusb
dmidecode 显示从BIOS中获取的硬件信息 dmesg 检测到的硬件和启动的消息 lsdev 显示关于安装硬件信息 cat /proc/devices 显示当前核心配置的设备 haparm - ...
- HTML jQuery实现的expend row
问 题:今天接到个任务,在一个老的系统页面里实现可展开的表格行. 寻找: 1.首先想到了在easyUI里见过的expand row form: 2.但是我们的老系统管理只有jQuery,如果使用eas ...
- 两台centos之间传送文件
https://www.cnblogs.com/pangguoming/p/9282762.html
- [IR] Time and Space Efficiencies Analysis of Full-Text Index Techniques
文章阅读:全文索引技术时空效率分析 LIU Xiao-ZhuPENG Zhi-Yong 根据全文索引实现技术的不同,将其分为三大类: 索引技术 (倒排文件.签名文件 .后缀树与后缀数组) 压缩与索引混 ...
- Html 助手
/*! * Html 助手 * version: 1.0.0-2018.07.25 * Requires ES6 * Copyright (c) 2018 Tiac * http://www.cnbl ...
- JVM的内存划分以及常用参数
JVM的主要划分为: 堆内存,虚拟机栈,方法区,程序计数器,本地方法栈 堆内存: 这部分区域是各个线程共享的,java的大部分对象都是储存在堆中. 1.堆在分配对象内存区域的时候可以分为两种,第一种叫 ...
- HTTP协议(web开发)
HTTP协议 HTTP协议简介 超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式.协作式和超媒体信息系统的应用层协议.HTTP是万维网的数 ...
- Solr7.4.0的API(Solrj)操作及项目中的使用
一.SolrJ的概念 solr单机版服务搭建:https://www.cnblogs.com/frankdeng/p/9615253.html solr集群版服务搭建:https://www.cnbl ...