Home  >  Article  >  PHP Framework  >  Laravel advanced learning: implementing distributed transactions based on reset

Laravel advanced learning: implementing distributed transactions based on reset

藏色散人
藏色散人forward
2021-11-09 15:37:281850browse

The following tutorial column of Laravel will introduce to you how LLaravel implements distributed transactions based on the reset mechanism. I hope it will be helpful to everyone!

Quick preview

Install the version between laravel5.5 - laravel8, and then install the fast service package

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

First create the ResetProductController.php controller, create the ResetProductModel.php model, and create two database tables, reset_transaction and reset_product. All these operations need to be completed by executing the following commands

php artisan resetTransact:create-examples

phpunit.xmlAdd testsuite 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>

Finally run the test command./vendor/bin/phpunit --testsuite=Transaction
The running results are as follows, 5 examples passed the test.

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)

Functional features

  • It can be used out of the box, no need to reconstruct the code of the original project, it is consistent with the mysql transaction writing method, simple and easy use.

  • Supports the service interface of http protocol. If you want to support other protocols, you need to rewrite the middleware.

  • Supports read committed, repeatable reading, and is synchronized with the transaction isolation level of mysql.

Principle Analysis

Having watched the movie "Edge of Tomorrow", you will know the operations of archiving and loading. This distributed transaction component imitates the principle of the "Edge of Tomorrow" movie. Every time a basic service is requested, the file is read at the beginning, and then the subsequent operations are continued. At the end, all operations are rolled back and archived, and finally the commit is executed successfully. The whole process follows a two-stage commit protocol, first prepare and finally commit.

How to use

Take the vendor/windawake/laravel-reset-transaction/tests/TransactionTest.php file as an example

<?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();
    }}

Personal Notes

I previously wrote the laravel rapid service package, but it did not solve the problem of data consistency. I tried to use XA, but XA can only solve the problem of multiple databases on a single machine and cannot solve the problem of servicing multiple machines. Then I tried to study tcc and seata, but after reading it, I was confused and at a loss. Being forced to a dead end, I had no choice but to create my own distributed transaction solution. For a long time, I have always thought that using MySQL alone cannot solve the problem of distributed transactions. Now I finally understand that there is still a way!

The above is the detailed content of Laravel advanced learning: implementing distributed transactions based on reset. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:learnku.com. If there is any infringement, please contact admin@php.cn delete