在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/PHP  數(shù)據(jù)庫/ Yii2 php循環(huán)使用mysql事務

Yii2 php循環(huán)使用mysql事務

hi,各位好。
現(xiàn)在有十條數(shù)據(jù)需要插入,同時有十條數(shù)據(jù)需要更新。暫記需要插入的數(shù)據(jù)為a1,a2,a3...a10,需要更新的數(shù)據(jù)為b1,b2,b3...b10。

需要保證所有的數(shù)據(jù)都同時操作成功,或者同時操作失敗。(即事務)。
而且需要將 a1插入后得到的主鍵ID更新到b1的一個字段,a2更新到b2的一個字段,依次類推。

我現(xiàn)在的做法是:

foreach($arr_a AS $a){
    //開啟事務
    //插入 a1 得到 id1
    //將ID更新到 b1
    //結(jié)束事務或者回滾事務
}

但是這樣的話會有幾個問題:
(1) 循環(huán)里面使用事務會導致性能問題吧?
(2) 如果拋異常了,會導致部分數(shù)據(jù)沒有辦法進行操作了。最外層加事務?

請問大神有什么好的解決方法嗎?求指導~感激不盡!

回答
編輯回答
小眼睛

需要保證所有的數(shù)據(jù)都同時操作成功,或者同時操作失敗。 是指如果a10操作失敗了,全部數(shù)據(jù)回滾到a1操作前嗎?如果是這樣的話,當然是吧事務放在循環(huán)外層最合適。

如果只是 “a1插入后得到的主鍵ID更新到b1的一個字段” 是一個事務,其中任意一組操作失敗不影響其他組操作的話,還是應該將事務放在循環(huán)內(nèi)。

// 用于記錄失敗的操作的key
$error = [];

foreach($arr_a AS $key => $a){
    $transaction = Yii::$app->getDb()->beginTransaction();

    try {
        //插入 a1 得到 id1
        //將ID更新到 b1
        
        $transaction->commit();
    } catch (\Exception $e) {

        // 回滾
        $transaction->rollBack();
        // 記錄失敗的操作的key
        $error[] = $key;

        // 這里不拋異常
        continue;
    }
}

// 對記錄的 $error 進行其他操作
2017年12月28日 13:33
編輯回答
入她眼

事務鎖很耗性能,最好在循環(huán)的外面放事務,這樣可以一起成功或者一起失敗。

2018年5月31日 00:36