一、总结
一句话总结:要程序里面支持事务,首先连接的数据库和数据表必须支持事务 mysql
1、InnoDB和MyISAM对事务的支持怎么样?
InnoDB支持事务
MyISAM不支持事务
2、thinkphp中事务无效如何解决?
可以首先尝试将数据表存储引擎改为:InnoDB
3、在哪里修改数据表的存储引擎?
design table->Options
二、thinkphp 的事务回滚处理 和 原始PHP的事务回滚实例
1、要程序里面支持事务,首先连接的数据库和数据表必须支持事务 mysql 为例:
数据库InnoDB支持 transactions
数据表支持事务:InnoDB 支持transaction
2、框架thinkphp 支持事务代码
public function testrollback()
{
$model1 = D(\'item\');
$model2 = D(\'vote\');
$model1->startTrans();
$res1 = $model1->where(\'id = 5\')->delete();
$res2 = $model2->where(\'id = 2\')->delete();
dump($res1);
dump($res2);
if($res1 && $res2){
$model1->commit(); //只有$res1 和 $res2 都执行成功是才真正执行上面的数据库操作
dump(\"commit\");
}else{
$model1->rollback(); // 条件不满足,回滚
dump(\"rollback\");
}
dump(\"over\");
exit;
}
3、原始PHP 代码事务实例
方法一:只支持数据库和数据表都是 innoDB 的情况
public function rollbackoriginal1()
{
$conn = mysql_connect(\'127.0.0.1\',\'summerzi\',\'summerzi\') or die(\'DB connection failed!\');
mysql_select_db(\'summer\',$conn);
mysql_query(\'set names \"GBK\"\');
mysql_query(\'BEGIN\');
$sql1 = \"INSERT INTO `summer_userdata`(`uid`,`type`,`target_id`) VALUES(41,1,233);\";
$sql2 = \"INSERT INTO `summer_userdata`(`uid`,`type`,`target_id`) VALUES(fdfd,2,235);\";
$res1 = mysql_query($sql1);
$res2 = mysql_query($sql2);
dump($sql1);
dump($sql2);
dump($res1);
dump($res2);
if($res1 && $res2){
mysql_query(\'COMMIT\');
dump(\'commit success!\');
}else{
mysql_query(\'ROLLBACK\');
dump(\'commit failed, rollback!\');
}
mysql_query(\'END\');
}
方法二:(注意:对于不支持事务的MyISAM引擎数据库可以使用表锁定的方法)
public function rollbackoriginal2()
{
$conn = mysql_connect(\'127.0.0.1\',\'summerzi\',\'summerzi\') or die(\'DB connection failed!\');
mysql_select_db(\'summer\',$conn);
mysql_query(\'set names \"GBK\"\');
mysql_query(\'SET AUTOCOMMIT=0\');////设置mysql不自动提交,需自行用commit语句提交
$sql1 = \"INSERT INTO `summer_userdata`(`uid`,`type`,`target_id`) VALUES(41,1,233);\";
$sql2 = \"INSERT INTO `summer_userdata`(`uid`,`type`,`target_id`) VALUES(44,2,235);\";
//mysql_query(\"LOCK TABLES `hmbl_userdata` WRITE\");//锁定表
$res1 = mysql_query($sql1);
$res2 = mysql_query($sql2);
dump($sql1);
dump($sql2);
dump($res1);
dump($res2);
//mysql_query(\"UNLOCK TABLES\");//解除锁定
if($res1 && $res2){
mysql_query(\'COMMIT\');
dump(\'commit success!\');
}else{
mysql_query(\'ROLLBACK\');
dump(\'commit failed, rollback!\');
}
mysql_query(\"SET AUTOCOMMIT=1\");
mysql_query(\'END\');
}
hp + mysql 对事务的处理比较简单,涉及到业务中多个数据操作,就可以考虑用事务处理
参考:thinkphp 的事务回滚处理 和 原始PHP的事务回滚实例 – summerzi – 博客园
https://www.cnblogs.com/summerzi/archive/2015/04/05/4393790.html
三、thinkphp事务处理无效时的解决办法,一击命中!
处理事务的时候,发现没有办法rollback,找了好久,我终于发现了问题所在:
以下干货:
数据表存储引擎改为:InnoDB
参考:thinkphp事务处理无效时的解决办法,一击命中! – CSDN博客
https://blog.csdn.net/yhq1988923/article/details/53516830
四、ThinkPHP 事务处理 (事务回滚) 、异常处理代码
事务代码写在try-catch之中
$trans_result = true;
$trans = M();
$trans->startTrans(); // 开启事务
try { // 异常处理
// 更新实施
$busbidList = M(\"busbid\")->where($map)->select();
foreach($busbidList as $k => $v) {
$map[\'id\'] = $busbidList[$k][\'id\'];
$result = M(\'busbid\')->where($map)->data($data)->save();
if ($result === false) {
throw new Exception(“错误原因”);
}
}
} catch (Exception $ex) {
$trans_result = false;
// 记录日志
Log::record(\"== xxx更新失败 ==\", \'DEBUG\');
Log::record($ex->getMessage(), \'DEBUG\');
}
if ($trans_result === false) {
$trans->rollback();
// 更新失败
$array[\'status\'] = 0;
} else {
$trans->commit();
// 更新成功
$array[\'status\'] = 1;
}
五、数据表修改储存引擎位置
六、thinkphp事务中if($ans1&&$ans2){}else{}方式和try{}catch{}方式事务操作的区别在哪里?
if_else方式是两个都要影响了数据库才能执行
try_catch方式是只要不发生异常就执行。
比如数据表中有id为12345的字段
比如说我们现在删除id为5和6的字段
在if_else中就是rollback,
在try_catch中就是commit
//19、测试事务操作
public function test18(){
Db::startTrans();
$ans1=db(\'myself_goods\')->delete(6);
$ans2=db(\'myself_goods\')->delete(5);
if($ans1&&$ans2){
// 提交事务
dump(\'commit\');
Db::commit();
}else{
// 回滚事务
Db::rollback();
dump(\'rollback\');
}
}
//18、测试事务操作
public function test17()
{
// 启动事务
Db::startTrans();
try{
$ans1=db(\'myself_goods\')->delete(6);
$ans2=db(\'myself_goods\')->delete(7);
dump(\'$ans1: \'.$ans1);
dump(\'$ans2: \'.$ans2);
// 提交事务
dump(\'commit\');
Db::commit();
} catch (\\Exception $e) {
// 回滚事务
Db::rollback();
dump(\'rollback\');
}
}
thinkphp事务处理以及无效时的解决方案介绍完毕
暂无评论内容