Home >PHP Framework >Laravel >Laravel advanced learning: implementing distributed transactions based on reset
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!
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)
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.
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.
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 = 'php ' . $num; $data = [ 'store_id' => 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(); }}
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!