zoukankan      html  css  js  c++  java
  • Yii2 事务操作

    官网关于Yii2 事务的说明文档

    http://www.yiiframework.com/doc-2.0/guide-db-active-record.html

    Working with Transactions

    There are two ways of using transactions while working with Active Record.

    The first way is to explicitly enclose Active Record method calls in a transactional block, like shown below,

    $customer = Customer::findOne(123);
    
    Customer::getDb()->transaction(function($db) use ($customer) {
        $customer->id = 200;
        $customer->save();
        // ...other DB operations...
    });
    
    // or alternatively
    
    $transaction = Customer::getDb()->beginTransaction();
    try {
        $customer->id = 200;
        $customer->save();
        // ...other DB operations...
        $transaction->commit();
    } catch(Exception $e) {
        $transaction->rollBack();
        throw $e;
    }

    The second way is to list the DB operations that require transactional support in the yiidbActiveRecord::transactions() method. For example,

    class Customer extends ActiveRecord
    {
        public function transactions()
        {
            return [
                'admin' => self::OP_INSERT,
                'api' => self::OP_INSERT | self::OP_UPDATE | self::OP_DELETE,
                // the above is equivalent to the following:
                // 'api' => self::OP_ALL,
            ];
        }
    }

    The yiidbActiveRecord::transactions() method should return an array whose keys are scenario names and values are the corresponding operations that should be enclosed within transactions. You should use the following constants to refer to different DB operations:

    Use the | operators to concatenate the above constants to indicate multiple operations. You may also use the shortcut constant OP_ALL to refer to all three operations above.

    Transactions that are created using this method will be started before calling beforeSave() and will be committed after afterSave() has run.

    Yiifans的翻译(权威指南)文档

    事务(Transaction)

    你可以向下面这样执行一个数据库事务:

    $transaction = $connection->beginTransaction();
    try {
        $connection->createCommand($sql1)->execute();
         $connection->createCommand($sql2)->execute();
        // ... 执行查询语句  ...
        $transaction->commit();
    } catch(Exception $e) {
        $transaction->rollBack();
    }

    还可以嵌套事务:

    // 外层事务
    $transaction1 = $connection->beginTransaction();
    try {
        $connection->createCommand($sql1)->execute();
     
        // 内层事务
        $transaction2 = $connection->beginTransaction();
        try {
            $connection->createCommand($sql2)->execute();
            $transaction2->commit();
        } catch (Exception $e) {
            $transaction2->rollBack();
        }
     
        $transaction1->commit();
    } catch (Exception $e) {
        $transaction1->rollBack();
    }

    多个sql执行(不同的表ActiveRecord)任意一个无法成功提交都要能回滚, 但这样执行的时候依然插入成功而没有回滚

     SysOrderFeedback正常save, SysOrderFeedbackServer中title必须为string

          $transaction = Yii::$app->db->beginTransaction();
            try {
                $sysOrderFeeback = new commonmodelsSysOrderFeedback();
                $sysOrderFeeback->categ = 1;
                $sysOrderFeeback->ltype = 1;
                $sysOrderFeeback->create_time = 1;
                $sysOrderFeeback->total = 1;
                $sysOrderFeeback->open_remark = 1;
                $sysOrderFeeback->save();
                // ...other DB operations...
                $sysOrderFeedbackServer = new commonmodelsSysOrderFeedbackServer();
                $sysOrderFeedbackServer->fid = 1;
                $sysOrderFeedbackServer->title = 1;
                $sysOrderFeedbackServer->create_time = 1;
                $sysOrderFeedbackServer->save();
                $transaction->commit();
            } catch (Exception $e) {
                $transaction->rollBack();
                throw $e;
            }

     打印:

    print_r($sysOrderFeedbackServer->errors);

    提示Array ( [title] => Array ( [0] => Title必须是一条字符串。 ) )

    开启事务,只要没有commit()即使验证成功的save也保存不了,如下

            $transaction = Yii::$app->db->beginTransaction();
                $sysOrderFeeback = new commonmodelsSysOrderFeedback();
                $sysOrderFeeback->categ = 1;
                $sysOrderFeeback->ltype = 1;
                $sysOrderFeeback->create_time = 1;
                $sysOrderFeeback->total = 1;
                $sysOrderFeeback->open_remark = 1;
                $sysOrderFeeback->save();

     后来改成下下策判断Model->errors 暂时解决问题

    $transaction = Yii::$app->db->beginTransaction();
            $sysOrderFeeback = new commonmodelsSysOrderFeedback();
            $sysOrderFeeback->categ = 1;
            $sysOrderFeeback->ltype = 1;
            $sysOrderFeeback->create_time = 1;
            $sysOrderFeeback->total = 1;
            $sysOrderFeeback->open_remark = 1;
            $sysOrderFeeback->save();
            // ...other DB operations...
            $sysOrderFeedbackServer = new commonmodelsSysOrderFeedbackServer();
            $sysOrderFeedbackServer->fid = 1;
            $sysOrderFeedbackServer->title = 1;
            $sysOrderFeedbackServer->create_time = 1;
            $sysOrderFeedbackServer->save();
            if (empty($sysOrderFeeback->errors) && empty($sysOrderFeedbackServer->errors)) {
                $transaction->commit();
                echo 'True';
            } else {
                $transaction->rollBack();
                echo 'false';
            }

    跟踪Debug

    关于更多的Yii2事务操作(事务级别、事务备份、事务有效性、多主从数据库事务)查看http://www.yiichina.com/doc/guide/2.0/db-dao

  • 相关阅读:
    maven mirror
    cas sso单点登录系列8_抛弃Https让Cas以Http协议提供单点登录服务
    cas sso单点登录系列7_ 单点登录cas常见问题系列汇总
    cas sso单点登录系列6_cas单点登录防止登出退出后刷新后退ticket失效报500错
    cas sso单点登录系列5_cas单点登录增加验证码功能完整步骤
    cas sso单点登录系列4_cas-server登录页面自定义修改过程(jsp页面修改)
    cas sso单点登录系列3_cas-server端配置认证方式实践(数据源+自定义java类认证)
    cas sso单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas协议终极分析
    cas sso单点登录系列1_cas-client Filter源码解码(转)
    Mysql事务机制
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4607981.html
Copyright © 2011-2022 走看看