阿江 2017-09-30 16:04:11 5324次浏览 1条回复 0 0 0

说明

学习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()运行后进行提交。

(全文完)

您需要登录后才可以回复。登录 | 立即注册