PHP在循环中使用事务,需要特别小心,因为稍不注意,就会造成事务失败,代码看着没问题,但最后事务没有成功。
比如下面这段代码:
for($logs as $log){
//开启事务
Db::startTrans();
//合规性判断
if($log['time'] == 0){
continue;
}
//一系列操作,略
//提交或回滚
if($ok){
Db::commit();
}else{
Db::rollback();
}
}
一眼看上去没啥问题,但是如果某条log的time
为0,执行了continue
,则它后面的log的事务都不会成功!
原因在于前面的Db::startTrans()
开启的事务,并没有因为continue
而自动关闭,所以之后的事务全部受到影响。
所以有时在日志里看到执行成功了,但是数据库里并没有记录,可能就是这个原因:循环中的事务没有正常rollback
或commit
。
找到了问题,解决方案也就随之出来了:
- 在循环中的每个
continue
或break
后都加上rollback
或commit
,正常结束事务; - 等所有判断都做完后再开启事务。