[Yii2笔记]012 AR事务操作(Working with Transactions) [ 技术分享 ]
说明
学习Yii Framework 2(易2框架)的过程是漫长的,也是充满乐趣的,以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现,提供了较完整的代码,供你参考。不妥之处,请多多指正!
原文网址:
http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#transactional-operations
8、Working with Transactions(事务操作)
本文主题:事务操作(Working with Transactions)
8、事务操作(Working with Transactions)
使用Active Record有两种方法可以进行事务操作。 第一种方法是明确将Active Record方法调用封装在一个事务块中,如下所示:
$customer = Customer::findOne(123);
Customer::getDb()->transaction(function($db) use ($customer) {
$customer->id = 200;
$customer->save();
// ...other DB operations...
});
//下例与上例等效:
$transaction = Customer::getDb()->beginTransaction();
try {
$customer->id = 200;
$customer->save();
// ...other DB operations...
$transaction->commit();
} catch(\Exception $e) {
$transaction->rollBack();
throw $e;
} catch(\Throwable $e) {
$transaction->rollBack();
throw $e;
}
注意:上例代码中我们使用了两个catch-blocks是为了兼容PHP 5.x和PHP 7.x。在PHP7.0中\Eexception继承自\Throwable接口,所以,如果你使用的PHP7.0及更高版本,你可以忽略\Exception部分。
文件位置:
D:\phpwork\basic\controllers\ArController.php
源代码:
public function actionAr() {
$country=CountryMysql::findOne(11);
CountryMysql::getDb()->transaction(function($db) use ($country) {
//$country->id = 11;
$country->population = 8;
$country->name = 'say it33';
$country->save();
});
echo "aa::".var_export($country,true);
}
测试结果:
aa::app\models\CountryMysql::__set_state(array( '_attributes' => array ( 'id' => 11, 'code' => 'ds', 'name' => 'say it33', 'population' => 8, ), '_oldAttributes' => array ( 'id' => 11, 'code' => 'ds', 'name' => 'say it33', 'population' => 8, ), '_related' => array ( ), '_errors' => array ( ), '_validators' => ArrayObject::__set_state(array( )), '_scenario' => 'default', '_events' => array ( ), '_behaviors' => array ( ), ))
文件位置:
D:\phpwork\basic\models\CountryMysql.php
源代码:
<?php
namespace app\models;
use Yii;
class CountryMysql extends \yii\db\ActiveRecord {
public static function tableName(){
return 'country';
}
public static function getDb(){
return \Yii::$app->db;
}
}
文件位置:
D:\phpwork\basic\controllers\ArController.php
源代码:
$country=CountryMysql::findOne(11);
$transaction = CountryMysql::getDb()->beginTransaction();
try {
$country->id = 16;
$country->save();
// ...other DB operations...
$transaction->commit();
} catch(\Exception $e) {
$transaction->rollBack();
throw $e;
} catch(\Throwable $e) {
$transaction->rollBack();
throw $e;
}
echo "aa::".var_export($country,true);
测试结果:
aa::app\models\CountryMysql::__set_state(array( '_attributes' => array ( 'id' => 14, 'code' => 'ds', 'name' => 'say it33', 'population' => 8, ), '_oldAttributes' => array ( 'id' => 14, 'code' => 'ds', 'name' => 'say it33', 'population' => 8, ), '_related' => array ( ), '_errors' => array ( ), '_validators' => ArrayObject::__set_state(array( )), '_scenario' => 'default', '_events' => array ( ), '_behaviors' => array ( ), ))
第二种方法是在yii\db\ActiveRecord::tractions()方法中列出需要执行事务支持的所有数据库操作。例如:
class Customer extends ActiveRecord
{
public function transactions()
{
return [
//默认场景封装update在事务体中
\yii\base\Model::SCENARIO_DEFAULT => self::OP_UPDATE,
'admin' => self::OP_INSERT,
'api' => self::OP_INSERT | self::OP_UPDATE | self::OP_DELETE,
// 'api' => self::OP_ALL,//与上句等效
];
}
}
yii\db\ActiveRecord::transactions()方法将返回一个数组,数组的键名是场景名称,键值对应将要在封装在事务中的操作。你将使用以下常量来代指不同的数据库操作: OP_INSERT: insert()执行的插入操作。 OP_UPDATE: update()执行的更新操作。 OP_DELETE: delete()执行的删除操作。
使用符号|连接以上常量可以定义多个操作,你也可以使用OP_ALL常量来表示上面全部三个操作。 使用此方法生成的事务将在调用beforeSave()前开始,并在afterSave()运行后进行提交。
(全文完)
阿江
注册时间:2015-10-18
最后登录:2024-03-03
在线时长:186小时21分
最后登录:2024-03-03
在线时长:186小时21分
- 粉丝94
- 金钱16816
- 威望160
- 积分20276