关于MySQL变量innodb_rollback_on_timeout一些讨论
2017-05-25 16:09
525 查看
原文链接: http://blog.csdn.net/lidan3959/article/details/8642706
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. |
下面通过一个示例来验证上面这段话。
2、示例
(1) innodb_rollback_on_timeout为OFFSession 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) |
(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) |
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,回滚事务。
来自:http://www.cnblogs.com/hustcat/archive/2012/11/18/2775487.html
相关文章推荐
- 关于MySQL变量innodb_rollback_on_timeout一些讨论
- 关于MySQL变量innodb_rollback_on_timeout一些讨论
- 关于MySQL变量innodb_rollback_on_timeout一些讨论
- 一个讨论引发关于js中函数声明,函数表达式,形参与变量声明赋值引发的一些事
- Android 用application保存全局变量,关于Android中传递数据的一些讨论
- [Mysql] 关于 Innodb 和 NDB 的一些事
- 一个讨论引发关于js中函数声明,函数表达式,形参与变量声明赋值引发的一些事(http://www.cnblogs.com/zhouyongtao/archive/2012/11/22/2783089)
- 关于MySQL的全局变量与会话变量的一些思考
- 【mysql】关于innodb中MVCC的一些理解
- Android 用application保存全局变量,关于Android中传递数据的一些讨论
- 【mysql】关于innodb中MVCC的一些理解
- 【mysql】关于innodb中MVCC的一些理解
- 【mysql】关于innodb中MVCC的一些理解
- [Mysql] 关于 Innodb 和 NDB 的一些事
- 关于MySQL的Myisam和Innodb的一些比较总结
- 关于MySQL的Myisam和Innodb的一些比较总结
- MySQL数据库innodb_rollback_on_timeout默认值的危害?
- 关于何种情况下使用DataGrid、DataList或Repeater的一些讨论
- 关于何种情况下使用DataGrid、DataList或Repeater的一些讨论
- 关于 Java 构造器的一些讨论