Maison  >  Article  >  développement back-end  >  Utiliser des transactions de base de données dans Laravel et détecter les exceptions après un échec de transaction

Utiliser des transactions de base de données dans Laravel et détecter les exceptions après un échec de transaction

高洛峰
高洛峰original
2017-02-09 09:23:212259parcourir

Description

Dans Laravel, si vous souhaitez exécuter un ensemble d'opérations dans une transaction de base de données, vous pouvez utiliser la méthode de transaction dans la façade DB. Si une exception est levée lors de la clôture d'une transaction, la transaction sera automatiquement restaurée. Si la clôture réussit, la transaction sera automatiquement validée. Vous n'avez pas à vous soucier de l'annulation ou de la validation manuelle de la transaction lorsque vous utilisez la méthode de transaction :

DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
});

Exploiter manuellement la transaction

Si vous souhaitez gérer manuellement la transaction et effectuer la opération de restauration ou de validation Si vous avez le contrôle total, vous pouvez utiliser la méthode beginTransaction sur la façade de la base de données :

DB::beginTransaction();

Vous pouvez également restaurer la transaction via la méthode rollBack :

DB::rollBack();

Enfin, vous pouvez le soumettre via la méthode commit Cette transaction :

DB::commit();

Remarque : La méthode de transaction de la façade DB peut également être utilisée pour contrôler la transaction du générateur d'instructions de requête et de l'ORM Eloquent.

Exemple

Supposons que vous souhaitiez stocker un point de connaissance dans la base de données. Ce point de connaissance appartient à deux points de test différents en même temps. les points sont une relation plusieurs-à-plusieurs, alors trois tables sont nécessaires pour implémenter cette structure de données :

Wiki de la table de points de connaissance :

---------------------------------------
id       title              content
---------------------------------------

Balise de table de points de test :

-------------------
id       name
-------------------

Connaissance du point de test Cliquez sur la table d'association wiki_tag_rel

----------------------------------
id          tag_id        wiki_id
----------------------------------

Vous devez maintenant ouvrir la transaction pour ajouter des données Wiki. Une fois le nouveau wiki ajouté avec succès, associez-le au point de test spécifié.

(Utilisez le générateur de requêtes dans Laravel Ou lorsque Eloquent ORM exécute la requête, si elle échoue, IlluminateDatabaseQueryException sera renvoyée)

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Database\QueryException;
use App\Wiki;

class TestController extends Controller
{
    //用DB facade的事务方法控制 查询语句构建器的事务
    public function storeWiki(Request $request)
    {
        DB::beginTransaction();
        try {
            $tagIds = explode(&#39;,&#39;, $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的事务方法控制 Eloquent ORM的事务
    public function createWiki(array $data)
    {
        DB::beginTransaction();
        try {
            $tagIds = explode(',', $data['tag_id']);
            $newWiki = Wiki::create([
                'title' => $data['title'],
                'content' => $data['content']
            ]);
            //Wiki和Tag两个Model使用了belongsToMany建立了多对多的关系
            //通过attach方法来附加wiki和tag的关系(写入中间表)
            $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']);
     }

}

                                   

Description

Dans Laravel, si vous souhaitez exécuter un ensemble d'opérations dans une transaction de base de données, vous pouvez utiliser la méthode de transaction dans le Façade DB. Si une exception est levée lors de la clôture d'une transaction, la transaction sera automatiquement restaurée. Si la clôture réussit, la transaction sera automatiquement validée. Vous n'avez pas à vous soucier de l'annulation ou de la validation manuelle de la transaction lorsque vous utilisez la méthode de transaction :

DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
});

Exploiter manuellement la transaction

Si vous souhaitez gérer manuellement la transaction et effectuer la opération de restauration ou de validation Si vous avez le contrôle total, vous pouvez utiliser la méthode beginTransaction sur la façade de la base de données :

DB::beginTransaction();

Vous pouvez également restaurer la transaction via la méthode rollBack :

DB::rollBack();

Enfin, vous pouvez le soumettre via la méthode commit Cette transaction :

DB::commit();

Remarque : La méthode de transaction de la façade DB peut également être utilisée pour contrôler la transaction du générateur d'instructions de requête et de l'ORM Eloquent.

Exemple

Supposons que vous souhaitiez stocker un point de connaissance dans la base de données. Ce point de connaissance appartient à deux points de test différents en même temps. les points sont une relation plusieurs-à-plusieurs, alors trois tables sont nécessaires pour implémenter cette structure de données :

Wiki de la table de points de connaissance :

---------------------------------------
id       title              content
---------------------------------------

Balise de table de points de test :

-------------------
id       name
-------------------

Connaissance du point de test Cliquez sur la table d'association wiki_tag_rel

----------------------------------
id          tag_id        wiki_id
----------------------------------

Vous devez maintenant ouvrir la transaction pour ajouter des données Wiki. Une fois le nouveau wiki ajouté avec succès, associez-le au point de test spécifié.

(Utilisez le générateur de requêtes dans Laravel Ou lorsque Eloquent ORM exécute la requête, si elle échoue, il renverra une exception IlluminateDatabaseQueryException)

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Database\QueryException;
use App\Wiki;

class TestController extends Controller
{
    //用DB facade的事务方法控制 查询语句构建器的事务
    public function storeWiki(Request $request)
    {
        DB::beginTransaction();
        try {
            $tagIds = explode(&#39;,&#39;, $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的事务方法控制 Eloquent ORM的事务
    public function createWiki(array $data)
    {
        DB::beginTransaction();
        try {
            $tagIds = explode(',', $data['tag_id']);
            $newWiki = Wiki::create([
                'title' => $data['title'],
                'content' => $data['content']
            ]);
            //Wiki和Tag两个Model使用了belongsToMany建立了多对多的关系
            //通过attach方法来附加wiki和tag的关系(写入中间表)
            $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']);
     }

}

Pour plus d'articles connexes sur l'utilisation des transactions de base de données dans Laravel et en capturant les exceptions après des échecs de transaction, veuillez faire attention au site Web PHP chinois !                                                                                             

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn