Laravel如何使用數(shù)據(jù)庫(kù)事務(wù)及捕獲事務(wù)失敗后的異常詳解
前言
如果大家在Laravel中要想在數(shù)據(jù)庫(kù)事務(wù)中運(yùn)行一組操作,則可以在 DB facade 中使用 transaction 方法。如果在事務(wù)的閉包內(nèi)拋出異常,事務(wù)將會(huì)被自動(dòng)還原。如果閉包運(yùn)行成功,事務(wù)將被自動(dòng)提交。
你不需要擔(dān)心在使用 transaction 方法時(shí)還需要親自去手動(dòng)還原或提交事務(wù):
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
手動(dòng)操作事務(wù)
如果你想手動(dòng)處理事務(wù)并對(duì)還原或提交操作進(jìn)行完全控制,則可以在 DB facade 使用 beginTransaction 方法:
DB::beginTransaction();
你也可以通過(guò) rollBack 方法來(lái)還原事務(wù):
DB::rollBack();
最后,可以通過(guò) commit 方法來(lái)提交這個(gè)事務(wù):
DB::commit();
注意: DB facade 的事務(wù)方法也可以用來(lái)控制 查詢語(yǔ)句構(gòu)造器 及 Eloquent ORM 的事務(wù)。
示例介紹
假設(shè)有要在數(shù)據(jù)庫(kù)中存儲(chǔ)一個(gè)知識(shí)點(diǎn),這個(gè)知識(shí)點(diǎn)同時(shí)屬于兩個(gè)不同的考點(diǎn),也就是考點(diǎn)和知識(shí)點(diǎn)這兩個(gè)數(shù)據(jù)是多對(duì)多的關(guān)系,那么要實(shí)現(xiàn)這種數(shù)據(jù)結(jié)構(gòu)就需要三個(gè)表:
知識(shí)點(diǎn)表 wiki:
--------------------------------------- id title content ---------------------------------------
考點(diǎn)表 tag:
------------------- id name -------------------
考點(diǎn)知識(shí)點(diǎn)關(guān)聯(lián)表 wiki_tag_rel
---------------------------------- id tag_id wiki_id ----------------------------------
現(xiàn)在要開(kāi)啟事務(wù)新增Wiki數(shù)據(jù),新增wiki成功后再把它關(guān)聯(lián)到指定的考點(diǎn)上去
(在laravel中使用查詢構(gòu)建器或者Eloquent ORM執(zhí)行query時(shí),如果失敗會(huì)返回 Illuminate\Database\QueryException 異常)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Database\QueryException;
use App\Wiki;
class TestController extends Controller
{
//用DB facade的事務(wù)方法控制 查詢語(yǔ)句構(gòu)建器的事務(wù)
public function storeWiki(Request $request)
{
DB::beginTransaction();
try {
$tagIds = explode(',', $request->get('tag_id'));
$wiki_id = DB::table('wiki')->insertGetId([
'title' => $request->get('title'),
'content' => $request->get('content')
]);
$relationData = [];
foreach($tagIds as $tagId) {
$data = ['wiki_id' => $wiki_id, 'tag_id' => $tagId];
$relationData[] = $data;
}
DB::table('wiki_tag_rel')->insert($relationData);
DB::commit();
} catch(\Illuminate\Database\QueryException $ex) {
DB::rollback();
return \Response::json(['status' => 'error', 'error_msg' => 'Failed, please contact supervisor']);
}
return \Response::json(['status' => 'ok']);
}
//用DB facade的事務(wù)方法控制 Eloquent ORM的事務(wù)
public function createWiki(array $data)
{
DB::beginTransaction();
try {
$tagIds = explode(',', $data['tag_id']);
$newWiki = Wiki::create([
'title' => $data['title'],
'content' => $data['content']
]);
//Wiki和Tag兩個(gè)Model使用了belongsToMany建立了多對(duì)多的關(guān)系
//通過(guò)attach方法來(lái)附加wiki和tag的關(guān)系(寫入中間表)
$newWiki->tags()->attach($tagIds);
DB::commit();
} catch(QueryException $ex) {
DB::rollback();
return \Response::json(['status' => 'error', 'error_msg' => 'Failed, please contact supervisor']);
}
return \Response::json(['status' => 'ok']);
}
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
PHP 面向?qū)ο蟪绦蛟O(shè)計(jì)(oop)學(xué)習(xí)筆記 (五) - PHP 命名空間
PHP 在 5.3.0 以后的版本開(kāi)始支持命名空間。什么是命名空間?從廣義上來(lái)說(shuō),命名空間是一種封裝事物的方法。在很多地方都可以見(jiàn)到這種抽象概念。2014-06-06
ThinkPHP實(shí)現(xiàn)生成和校驗(yàn)驗(yàn)證碼功能
這篇文章主要為大家詳細(xì)介紹了ThinkPHP實(shí)現(xiàn)生成和校驗(yàn)驗(yàn)證碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
php數(shù)組應(yīng)用之比較兩個(gè)時(shí)間的相減排序
因網(wǎng)站需要實(shí)現(xiàn)兩個(gè)時(shí)間段的所有小說(shuō)的收藏,點(diǎn)擊等操作,特把同事寫的代碼收藏下,以后有需要研究2008-08-08
使用PHP?Smarty處理表單數(shù)據(jù)的方法
這篇文章主要介紹了如何使用PHP?Smarty處理表單數(shù)據(jù),首先需要下載Smarty庫(kù)并將其解壓到你的項(xiàng)目,下面通過(guò)本文結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2023-08-08
php include類文件超時(shí)問(wèn)題處理
這篇文章主要介紹了php include類文件超時(shí)問(wèn)題處理,需要的朋友可以參考下2015-02-02

