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 協議》,轉載必須註明作者和本文連結