1. 程式人生 > >ThinkPHP 多表回滾無效

ThinkPHP 多表回滾無效

今天首次用到了多表回滾,遇到了一個坑。錯誤程式碼如下:

try{
    $Member = D("Member");
    $Member->startTrans();
    $member_condition['id'] = 11641;
    $member_data['id'] = 10000;
    $member_res = $Member->where($member_condition)->save($member_data);

    if ($member_res === 1) {
        try{
            $User
= D("User"); $User->startTrans(); $user_condition['account'] = '111111'; $user_data['username'] = "4324"; $user_res = $User->where($user_condition)->save($user_data); if ($user_res === 1) { $User->commit(); $Member
->commit(); echo "全部修改成功"; } else { $User->rollback(); $Member->rollback(); echo "User表未受影響,全部回滾!"; } }catch (Exception $e){ $User->rollback(); $Member->rollback(); echo
"User修改異常,全部回滾!"; } } else { $Member->rollback(); echo "Member表未受影響,回滾!"; } }catch (Exception $e){ $Member->rollback(); echo "Member修改異常!"; }

我的思路是對 MemberUser 分別開啟事務,只要有一個表修改失敗,那麼就全部回滾。但事實確是開啟了兩個事務後,這兩個事務都無法回滾。如果只開啟一個事務,那麼該事務是可以回滾的。在tp官方文件裡面也沒找到什麼解釋。解決方法如下所示:

try{
    $Model = M();
    $Model->startTrans();
    $member_condition['id'] = 11641;
    $member_data['id'] = 10000;
    $member_res = $Model->table('party_member')->where($member_condition)->save($member_data);

    $user_condition['account'] = '111111';
    $user_data['username'] = "4324";
    $user_res = $Model->table('party_user')->where($user_condition)->save($user_data);

    if ($member_res === 1 && $user_res === 1) {
        echo "commit";
        $Model->commit();
    }
    else{
        echo "rollback";
        $Model->rollback();
    }
}catch (Exception $e){
    echo "發生異常";
    $Model->rollback();
}

對於多表的事務處理,先用 M 函式例項化一個空物件,使用 table 方法進行多個表的操作,如果操作成功則提交,失敗則回滾。

另外一點需要說明的是,在有些整合環境中MySQL預設的引擎是 MyISAM,若想提供事務支援,需將資料庫引擎改為 InnoDB