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 !
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=Transaction
Exé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 = '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(); }}
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!