Maison  >  Article  >  cadre php  >  Apprentissage avancé Laravel : implémentation de transactions distribuées basées sur la réinitialisation

Apprentissage avancé Laravel : implémentation de transactions distribuées basées sur la réinitialisation

藏色散人
藏色散人avant
2021-11-09 15:37:281846parcourir

La colonne tutorielle suivante de Laravel vous présentera comment LLaravel implémente les transactions distribuées basées sur le mécanisme de réinitialisation. J'espère qu'elle sera utile à tout le monde !

Aperçu rapide

Installez la version entre laravel5.5 - laravel8, puis installez le package de service rapide

composer nécessite windawake/laravel-reset-transaction dev-master

Créez d'abord le contrôle ResetProductController.php Converter, créez le modèle ResetProductModel.php et créez deux tables de base de données, reset_transaction et reset_product. Toutes ces opérations doivent être effectuées en exécutant les commandes suivantes

php artisan resetTransact:create-examples

phpunit.xml pour ajouter la suite de tests Transaction

<?xml version="1.0" encoding="UTF-8"?><phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         colors="true">
    <testsuites>
        ......        <testsuite name="Transaction">
            <directory>./vendor/windawake/laravel-reset-transaction/tests</directory>
        </testsuite>
    </testsuites>
    ......</phpunit>

Enfin, exécutez la commande de test ./vendor/bin/phpunit --testsuite=TransactionExécuter les résultats Comme indiqué ci-dessous, 5 exemples ont réussi le test. ./vendor/bin/phpunit --testsuite=Transaction
运行结果如下所示,5个例子测试通过。

oot@DESKTOP-VQOELJ5:/web/linux/php/laravel/laravel62# ./vendor/bin/phpunit --testsuite=TransactionPHPUnit 8.5.20 by Sebastian Bergmann and contributors......                                                               5 / 5 (100%)Time: 219 ms, Memory: 22.00 MB

OK (5 tests, 5 assertions)

功能特性

  • 开箱即用,不需要重构原有项目的代码,与mysql事务写法一致,简单易用。

  • 支持http协议的服务化接口,想要支持其它协议则需要重写中间件。

  • 支持读已提交,可重复读,与mysql的事务隔离级别同步。

原理解析

看过《明日边缘》电影就会知道,存档和读档的操作。这个分布式事务组件仿造《明日边缘》电影的原理,每次请求基础服务一开始时读档,然后继续后面的操作,结束时所有操作全部回滚并且存档,最后commit把存档全部执行成功。整个过程是遵守两段提交协议,先prepare,最后commit。

如何使用

vendor/windawake/laravel-reset-transaction/tests/TransactionTest.php

<?php
namespace Tests\Feature;use Tests\TestCase;use Illuminate\Support\Facades\DB;class TransactionTest extends TestCase{
    public function testCreateWithCommit()
    {
        $num = rand(1, 10000);
        $productName = &#39;php &#39; . $num;
        $data = [
            &#39;store_id&#39; => 1,
            'product_name' => $productName,
        ];
        // 开启分布式事务,其实是生成全局唯一id
        $transactId = $this->beginDistributedTransaction();
        $header = [
           在header 'transact_id' => $transactId,
        ];
        // 分布式事务内,请求都需要在request header带上transact_id
        $response = $this->post('api/resetProduct', $data, $header);
        $product = $response->json();
        // 分布式事务提交,也是接口请求,把之前的存档记录全部处理
        $this->commitDistributedTransaction($transactId);

        $response = $this->get('/api/resetProduct/' . $product['pid']);
        $product = $response->json();
        $this->assertEquals($productName, $product['product_name']);
    }

    private function beginDistributedTransaction()
    {
        return session_create_id();
    }

    private function commitDistributedTransaction($transactId)
    {
        $response = $this->post('/api/resetTransaction/commit', [], ['transact_id' => $transactId]);
        return $response->getStatusCode();
    }

    private function rollbackDistributedTransaction($transactId)
    {
        $response = $this->post('/api/resetTransaction/rollback', [], ['transact_id' => $transactId]);
        return $response->getStatusCode();
    }}

Fonctionnalités fonctionnelles

  • Utilisé prêt à l'emploi, pas besoin de reconstruire le code du projet original, cohérent avec l'écriture des transactions mysql, utilisation simple et facile. 🎜
  • 🎜Prend en charge l'interface de service du protocole http Si vous souhaitez prendre en charge d'autres protocoles, vous devez réécrire le middleware. 🎜
  • 🎜Prend en charge la lecture validée et répétable et est synchronisé avec le niveau d'isolation des transactions de MySQL. 🎜
🎜🎜🎜Analyse des principes🎜🎜Si vous avez regardé le film "Edge of Tomorrow", vous connaîtrez l'opération d'archivage et de chargement. Ce composant de transaction distribuée imite le principe du film "Edge of Tomorrow". Chaque fois qu'un service de base est demandé, le fichier est lu au début, puis les opérations suivantes sont poursuivies à la fin, toutes les opérations sont annulées et. archivé, et enfin le commit est exécuté avec succès. L'ensemble du processus suit un protocole de validation en deux étapes : d'abord la préparation et enfin la validation. 🎜🎜🎜🎜Comment utiliser🎜🎜Prenons le fichier vendor/windawake/laravel-reset-transaction/tests/TransactionTest.php comme exemple🎜rrreee🎜Notes personnelles🎜🎜J'ai écrit un laravel rapid package de services avant, mais cela ne résout pas le problème de cohérence des données. J'ai essayé d'utiliser XA, mais XA ne peut résoudre que le problème de plusieurs bases de données sur une seule machine et ne peut pas résoudre le problème de la maintenance de plusieurs machines. Ensuite, j'ai essayé d'étudier TCC et Seata, mais après l'avoir lu, j'étais confus et perdu. Contraint à une impasse, je n’ai eu d’autre choix que de créer ma propre solution de transactions distribuées. Pendant longtemps, j'ai toujours pensé qu'utiliser MySQL à lui seul ne pouvait pas résoudre le problème des transactions distribuées. Maintenant, je comprends enfin qu'il existe encore un moyen ! 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer