本文做一個Laravel數據庫事務的介紹。
一 、事務將一堆的數據庫操作組合到一個工作單元中執行
transaction 方法接受一個可選的第二個參數,該參數定義在發生死鎖時,應該重新嘗試事務的次數。一旦這些嘗試都用盡了,就會拋出一個異常:
二 、事務的四個特性
1、原子性(atomicity)原子性是指整個數據庫事務是不可分割的工作單位。
2、一致性(consistency)一致性指事務將數據庫從一種狀態轉變爲下一種一致的狀態。在事務開始之前和事務結束之後,數據庫的完整性約束沒有被破壞。
3、隔離性(isolation)一個事務的影響在該事務提交之前對其他事務都不可見------這通過鎖來實現。
4、持久性(durability)事務一旦提交,其結果就是永久性的。
三、Mysql中的存儲引擎
1、Mysql服務器層不管理事務,事務是由下層的存儲引擎實現的。
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);
});
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 的事務。