【Laravel】資料庫事務
阿新 • • 發佈:2019-01-06
最近公司專案集成了一個支付的模組。由於網路世界是不確定的。說不定哪個操作就出了問題。為了保證資料的正確性我們不得不考慮使用資料庫事務這一特性。本文做一個Laravel資料庫事務的介紹。
知識回顧
一 、事務將一堆的資料庫操作組合到一個工作單元中執行二 、事務的四個特性
1、原子性(atomicity)原子性是指整個資料庫事務是不可分割的工作單位。
2、一致性(consistency)一致性指事務將資料庫從一種狀態轉變為下一種一致的狀態。在事務開始之前和事務結束之後,資料庫的完整性約束沒有被破壞。
3、隔離性(isolation)一個事務的影響在該事務提交之前對其他事務都不可見------這通過鎖來實現。
4、永續性(durability)事務一旦提交,其結果就是永久性的。
三、Mysql中的儲存引擎
1、Mysql伺服器層不管理事務,事務是由下層的儲存引擎實現的。
2、在MySQL 5.1之前的版本中,預設的搜尋引擎是MyISAM,從MySQL 5.5之後的版本中,預設的搜尋引擎變更為InnoDB。
3、Mysql提供了兩種事務型的儲存引擎:InnoDB和NDB Cluster,而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::rollBack();
最後,
您可以通過 commit 方法提交事務,當事務進行提交(commit)或者回滾(rollBack)時都會取消鎖:
DB::commit();
例子如下:
DB::beginTransaction();//開啟事務 try { //這裡省略了業務邏輯程式碼
if($isSuccess){
DB::commit();//成功,提交事務
}
//思考->如果事務開啟不提交會發生什麼後果??? } catch(\Illuminate\Database\QueryException $ex) { DB::rollback();//失敗,回滾事務 echo 'error'; } echo 'success';
如果MySQL存在沒有提交的事務,那麼這時候 AUTOCOMMIT 自動提交的引數應該是為 0 的。如果通過其他的語言的MySQL驅動來操作的話,這些驅動一般都帶有自動恢復 AUTOCOMMIT 的功能,在請求處理完成後會自動 ROLLBACK 沒有處理的事務。注意:使用
DB
門面的事務方法還可以用於控制查詢構建器和 Eloquent ORM 的事務。