Innodb的事务处理autocommit参数问题

在一个开源项目中看到Mysql类事务处理的逻辑:

//开启事务
function strans(){
   mysql_query("start transaction");//开始一个事务  
   mysql_query("SET AUTOCOMMIT=0"); //设置事务不自动commit
}  
//提交事务
function commit(){
   mysql_query("commit");
   mysql_query("SET AUTOCOMMIT=1");
}
//回滚事务
function rollback(){
   mysql_query("rollback");
   mysql_query("SET AUTOCOMMIT=1");
}
类中频繁地对autocommit进行了设置,可见其对autocommit的实际意义并没有理解。

在Innodb引擎中,事务是自动开启的,这就存在一个问题:事务需要提交才能被执行。但是实际应用中可能很多情况只有一条sql,如果也要手动提交才能被执行的话就太麻烦了,所以Innodb引擎默认缺省的autocommit=on(show variables like '%autocommit%'),即自动提交。

但是每一条sql都自动提交(每一条sql都是一个独立事务)的话,就无法构建多张表的事务管理了。所以有必要将N条sql组成一个事务进行提交。主要有以下两种方法:

1:通过设置autocommit:即手动设置在一段代码区间内,不自动提交,区间内的所有sql,组成一个事务手动提交;执行完毕,再还原为自动提交。

$db->query('set autocommit=0');
$db->query('');
$db->query('');
if($db->query('commit')){
   //事务执行成功
}
else{
   $db->query('rollback');
}
$db->query('set autocommit=1'); //必须恢复autocommit=1,否则后面所有sql无法执行
$db->query(''); //恢复autocommit=1后,该语句方可成功执行

2:显示打开一个事务,该方法中,start transaction到commit(rollback)之间的sql,将会组成一个事务。

$db->query('start transaction');
$db->query('');
$db->query('');
if($db->query('commit')){
   //事务执行成功
}
else{
   $db->query('rollback');
}
$db->query(''); //该条数据可以插入

需要说明的是,开启事务之后,在commit(rollback)之前的sql,如果有select,且select的是当前事务会更新的行(表),那么提取出来的将是事务提交后的预定值,而不是数据库中存储的当前值。如下:

start transaction
update tableA set columnA=B  //原columnA=C
select columnA from tableA  //结果为B,而不是C(尽管事务未被提交)
commit

猜你喜欢

转载自blog.csdn.net/eclothy/article/details/50380639