Laravel數據庫事務

本文做一個Laravel數據庫事務的介紹。

 事務將一堆的數據庫操作組合到一個工作單元中執行


 、事務的四個特性

1、原子性(atomicity)原子性是指整個數據庫事務是不可分割的工作單位。
2、一致性(consistency)一致性指事務將數據庫從一種狀態轉變爲下一種一致的狀態。在事務開始之前和事務結束之後,數據庫的完整性約束沒有被破壞。

3、隔離性(isolation)一個事務的影響在該事務提交之前對其他事務都不可見------這通過鎖來實現。

4、持久性(durability)事務一旦提交,其結果就是永久性的。


Mysql中的存儲引擎

1Mysql服務器層不管理事務,事務是由下層的存儲引擎實現的。

2在MySQL 5.1之前的版本中,默認的搜索引擎是MyISAM,從MySQL 5.5之後的版本中,默認的搜索引擎變更爲InnoDB。

而MyISAM不支持事務。


死鎖

1.什麼是死鎖?死鎖是指兩個或者多個事務在同一資源上相互佔用,並請求鎖定對方佔用的資源,從而導致惡性循環。

2.爲什麼要避免死鎖?導致慢查詢

3.如何解決?Mysql提供了死鎖檢測和死鎖超時機制,

Laravel中的事務

方式一:閉包方式實現事務

您可以在 DB facade 上使用 transaction 方法,在數據庫事務中運行一組操作。如果在事務 Closure 中拋出一個異常,那麼事務將自動回滾。如果 Closure 成功執行,事務將自動被提交。您不需要擔心在使用事務方法時手動回滾或提交。
//模擬用戶233向用戶666轉賬1元
DB::transaction(function () {
    DB::table('transactions')->where('user_id',666)increment('blance' , 1);

    DB::table('transactions')->where('user_id',233)->decrement('balance' , 1);
});
transaction 方法接受一個可選的第二個參數,該參數定義在發生死鎖時,應該重新嘗試事務的次數。一旦這些嘗試都用盡了,就會拋出一個異常:


DB::transaction(function () {
   DB::table('transactions')->where('user_id',666)increment('blance' , 1);

   DB::table('transactions')->where('user_id',233)->decrement('balance' , 1);
}, 3);

如果閉包內部需要調用外部的參數可以使用下面的方式向閉包傳參:


DB::transaction(function use ($amount) () {
   DB::table('transactions')->where('user_id',666)increment('blance' , $amount);

   DB::table('transactions')->where('user_id',233)->decrement('balance' , $amount);
}, 3);

方式二:手動操作事務

如果您想要手工開始一個事務,並且對回滾和提交有完全的控制,那麼您可以在 DB facade 上使用:

beginTransaction 方法:


DB::beginTransaction();
您可以通過 rollBack 方法回滾事務:

DB::rollBack();

最後, 您可以通過 commit 方法提交事務,當事務進行提交(commit)或者回滾(rollBack)時都會取消鎖:

DB::commit();
例子如下:


DB::beginTransaction();	//開啓事務
try {
    //這裏省略了業務邏輯代碼
    if($isSuccess){        DB::commit();	//成功,提交事務    }   //思考->如果事務開啓不提交會發生什麼後果???
} catch(\Illuminate\Database\QueryException $ex) {
    DB::rollback();	//失敗,回滾事務
    echo 'error';
}
echo 'success';

注意:使用 DB 門面的事務方法還可以用於控制查詢構建器和 Eloquent ORM 的事務。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章