Laravel eloquent 的事務與事件

lufeijun1234發表於2020-06-20

laravel 的 Eloquent ORM 的事件機制,為我們提供了一種解耦程式碼的可能性,但是,如果在一個事務中觸發其對應的事件時,無論事務最後是否 commit ,其對應的事件都會被觸發,這樣在處理業務邏輯的情況下會導致一些問題;

User::updated(function( User $user) {
    $logs = [];
    if ( $user->isDirty('city') ) {
        $logs[] = '將城市設定為' . $user->city;
    }

    if ( $user->isDirty('address') ) {
        $logs[] = '將地址設定為' . $user->address;
    }

    // 儲存日誌
    $log = new UserLog;
    $log->user_id = $user->id;
    $log->log = implode('、', $logs);
    $log->save();
}

分析

以上程式碼其功能為:當使用者更新自己的城市、地址資訊時,同時將日誌儲存起來。

在業務邏輯程式碼部分,在更新使用者資訊時是開啟事務的,Eloquent 在呼叫 save 時,觸發 updated 事件,事件同步被執行,所以最後是否儲存到資料庫取決於業務邏輯部分的 commit/rollBack 。因此在這塊可以恰好做到資料一致性。




User::created(function( User $user) {

    // 傳送郵件

    // 傳送使用者簡訊

    // 通知資料模組,通過佇列等其他非同步邏輯

});

分析

以上程式碼其功能為:當使用者完成註冊邏輯時,觸發其他業務邏輯,比如:傳送簡訊、傳送郵箱、資料模組同步

在業務邏輯程式碼部分,使用者註冊是開啟事務的,當呼叫 Eloquent 的 save 方法時,會觸發 created 事件,事件會同步執行,所以上述程式碼會被正常執行,但是如果在業務邏輯部分出錯,導致事務回滾( rollBack ),但事件部分程式碼邏輯卻被觸發了,所以這裡會有一些坑,需要注意。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章