Laravel進階學(xué)習(xí)之基于reset實現(xiàn)分布式事務(wù)

下面由laravel教程欄目帶大家推薦介紹關(guān)于llaravel怎么基于reset機制實現(xiàn)分布式事務(wù),希望對大家有所幫助!

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

快速預(yù)覽

安裝laravel5.5 – laravel8之間的版本,然后安裝快速服務(wù)化的package

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

首先創(chuàng)建ResetProductController.php控制器,創(chuàng)建ResetProductModel.php模型,創(chuàng)建reset_transaction和reset_product兩張數(shù)據(jù)庫表。這些操作只需要執(zhí)行下面命令全部完成

php artisan resetTransact:create-examples

phpunit.xml增加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>

最后運行測試命令 ./vendor/bin/phpunit –testsuite=Transaction
運行結(jié)果如下所示,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)

功能特性

  • 開箱即用,不需要重構(gòu)原有項目的代碼,與mysql事務(wù)寫法一致,簡單易用。

  • 支持http協(xié)議的服務(wù)化接口,想要支持其它協(xié)議則需要重寫中間件。

  • 支持讀已提交,可重復(fù)讀,與mysql的事務(wù)隔離級別同步。

原理解析

看過《明日邊緣》電影就會知道,存檔和讀檔的操作。這個分布式事務(wù)組件仿造《明日邊緣》電影的原理,每次請求基礎(chǔ)服務(wù)一開始時讀檔,然后繼續(xù)后面的操作,結(jié)束時所有操作全部回滾并且存檔,最后commit把存檔全部執(zhí)行成功。整個過程是遵守兩段提交協(xié)議,先prepare,最后commit。

如何使用

以vendor/windawake/laravel-reset-transaction/tests/TransactionTest.php文件為例子

<?php namespace TestsFeature;use TestsTestCase;use IlluminateSupportFacadesDB;class TransactionTest extends TestCase{     public function testCreateWithCommit()     {         $num = rand(1, 10000);         $productName = 'php ' . $num;         $data = [             'store_id' => 1,             'product_name' => $productName,         ];         // 開啟分布式事務(wù),其實是生成全局唯一id         $transactId = $this->beginDistributedTransaction();         $header = [            在header 'transact_id' => $transactId,         ];         // 分布式事務(wù)內(nèi),請求都需要在request header帶上transact_id         $response = $this->post('api/resetProduct', $data, $header);         $product = $response->json();         // 分布式事務(wù)提交,也是接口請求,把之前的存檔記錄全部處理         $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快速服務(wù)化包,但是它沒有解決數(shù)據(jù)一致性的問題。嘗試用XA,但是XA只能解決單機多個數(shù)據(jù)庫,沒法解決多臺機器服務(wù)化的問題。然后我又嘗試去研究tcc和seata,但是看完后一臉懵逼,不知所措。無奈被逼上絕路,沒辦法了只能自創(chuàng)分布式事務(wù)解決方案。一直以來,我一直以為單單只用mysql是沒法解決分布式事務(wù)的問題,現(xiàn)在終于明白,還是有辦法滴!

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊13 分享