Yii2中事务的使用实例代码详解
前言一般我们做业务逻辑,都不会仅仅关联一个数据表,所以,会面临事务问题。 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。 准备数据库引擎为innodb 本文使用的yii版本为2.0.5,只要是2.0以上就没有问题 运行环境为PHP7.0.0,Mysql5.6 Yii中的事务处理异常 db->beginTransaction();
try {
for($i=1;$i<=3;$i++){
$test = new Areas();
$test->name = 'name'.$i;
$test->sort=1;
if($test->save()){
echo "save $i | ";
}
}
$test = new Areas();
$test->name = 'ab'.$i;
$test->sorta=1; //写入不存在的字段
if(!$test->save()){
"save fail"; //如果没有写入就输出
}
//提交
$tr->commit();
} catch (Exception $e) {
//回滚
$tr->rollBack();
echo "rollback";
}
}
运行结果 注意,因为最后的数据没有插入成功,触发了事务的回滚,所以数据表没有新增数据产生。 触发事务回滚的原因是代码出现了异常(Exception)。 处理数据失败一般来讲,我们的运行中的代码是不会出现这种明显的异常,这种异常会在开发测试过程中消灭掉。 而真正造成数据需要回滚的是我们的某个业务出现问题,导致没有写入部分的数据。 db->beginTransaction();
try {
for($i=1;$i<=3;$i++){
$test = new Areas();
$test->name = 'name'.$i;
$test->sort=1;
if($test->save()){
echo "save $i | ";
}
}
$test = new Areas();
$test->name = null; //数据库设计name不能为空,人为造成写入失败。
$test->sort=1; //写入不存在的字段
if(!$test->save()){
echo "save fail"; //如果没有写入就输出
}
//提交
$tr->commit();
} catch (Exception $e) {
//回滚
$tr->rollBack();
echo "rollback";
}
}
运行结果如下,数据库插入了三条数据。 也就是说,如果因为业务逻辑导致某个数据表没有写入数据,也没有出现对应的回滚。 改进方案如下 db->beginTransaction();
try {
for($i=1;$i<=3;$i++){
$test = new Areas();
$test->name = 'name'.$i;
$test->sort=1;
if($test->save()){
echo "save $i | ";
}
}
$test = new Areas();
$test->name = null; //数据库设计name不能为空,人为造成写入失败。
$test->sort=1; //写入不存在的字段
if(!$test->save()){
throw new yiidbException(); //手动抛出异常,再由下面捕获。
}
//提交
$tr->commit();
} catch (Exception $e) {
//回滚
$tr->rollBack();
echo "rollback";
}
}
运行结果如下,数据库没有插入新数据,事务被回滚。 分散的数据处理由于实际项目的复杂程度,导致我们的数据库操作分散在不同的Model中。 所以,实际项目的代码不会是上面的样子。
实际代码 正常的结果如下 如果把初始化用户余额部分的user_id没有传递成功,返回的结果如下 我们可以针对具体情况定位到错误所在位置,及时修改。 从上面的实际代码可以看出,创建了事务,只要在范围内,就算是引入的别的Model也能把异常NG返回,完成回滚操作。 一般情况下,整个Yii应用使用了同一个数据库连接,或者说是使用了单例。 而在yiidbConnection中,又对事务对象进行了缓存: 因此,可以认为整个Yii应用,使用了同一个 Transaction 对象,也就是说, Transaction::_level 在整个应用的生命周期中,是有延续性的。 这是实现事务嵌套的关键和前提。 以上所述是小编给大家介绍的Yii2中事务的使用实例代码详解。编程之家 52php.cn 收集整理的教程希望能对你有所帮助,如果觉得编程之家不错,可分享给好友!感谢支持。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |