ホームページ  >  記事  >  PHPフレームワーク  >  Laravel の高度な学習: リセットに基づいた分散トランザクションの実装

Laravel の高度な学習: リセットに基づいた分散トランザクションの実装

藏色散人
藏色散人転載
2021-11-09 15:37:281985ブラウズ

Laravel の次のチュートリアル コラムでは、LLaravel がリセットメカニズムに基づいて分散トランザクションを実装する方法を紹介します。

クイックプレビュー

laravel5.5からlaravel8までのバージョンをインストールしてから、高速サービスパッケージをインストールします

composer require windawake / laravel-reset-transaction dev-master

まず、ResetProductController.php コントローラーを作成し、ResetProductModel.php モデルを作成し、2 つのデータベース テーブル (reset_transaction と replace_product) を作成します。これらの操作はすべて、次のコマンドを実行して完了する必要があります。

php artisan resetTransact:create-examples
phpunit.xmlテストスイート トランザクションを追加

<?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>
最後にテスト コマンドを実行します

./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 のトランザクション分離レベルと同期されます。

原理分析

映画「エッジ オブ トゥモロー」を観れば、アーカイブとロードの操作がわかるでしょう。この分散トランザクション コンポーネントは、映画「Edge of Tomorrow」の原理を模倣しており、基本的なサービスが要求されるたびに、最初にファイルが読み込まれ、その後の操作が継続され、最後にすべての操作がロールバックされ、アーカイブされ、最後にコミットが正常に実行されます。プロセス全体は、最初に準備し、最後にコミットする 2 段階のコミット プロトコルに従います。

使用方法

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();
    }}
個人的なメモ

以前、laravel Rapid Service パッケージを作成しましたが、データの一貫性の問題は解決されませんでした。 XA を使用しようとしましたが、XA は 1 台のマシン上の複数のデータベースの問題を解決することしかできず、複数のマシンにサービスを提供する問題は解決できません。そこで、tccとseataを勉強しようとしたのですが、読んだ後、混乱してしまい、途方に暮れてしまいました。行き詰まりに追い込まれた私には、独自の分散トランザクション ソリューションを作成する以外に選択肢はありませんでした。私は長い間、MySQL だけを使用するだけでは分散トランザクションの問題を解決できないと常々思っていましたが、まだ解決方法があることがようやく理解できました。

以上がLaravel の高度な学習: リセットに基づいた分散トランザクションの実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。