快速预览安装laravel5.5 - laravel8之间的版本,然后安装快速服务化的package
composer require windawake/laravel-reset-transaction dev-master
首先创建resetproductcontroller.php控制器,创建resetproductmodel.php模型,创建reset_transaction和reset_product两张数据库表。这些操作只需要执行下面命令全部完成
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
运行结果如下所示,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 mbok (5 tests, 5 assertions)
功能特性开箱即用,不需要重构原有项目的代码,与mysql事务写法一致,简单易用。
支持http协议的服务化接口,想要支持其它协议则需要重写中间件。
支持读已提交,可重复读,与mysql的事务隔离级别同步。
原理解析看过《明日边缘》电影就会知道,存档和读档的操作。这个分布式事务组件仿造《明日边缘》电影的原理,每次请求基础服务一开始时读档,然后继续后面的操作,结束时所有操作全部回滚并且存档,最后commit把存档全部执行成功。整个过程是遵守两段提交协议,先prepare,最后commit。
如何使用以vendor/windawake/laravel-reset-transaction/tests/transactiontest.php文件为例子
<?phpnamespace 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(); }}
个人笔记我之前写了laravel快速服务化包,但是它没有解决数据一致性的问题。尝试用xa,但是xa只能解决单机多个数据库,没法解决多台机器服务化的问题。然后我又尝试去研究tcc和seata,但是看完后一脸懵逼,不知所措。无奈被逼上绝路,没办法了只能自创分布式事务解决方案。一直以来,我一直以为单单只用mysql是没法解决分布式事务的问题,现在终于明白,还是有办法滴!
以上就是laravel进阶学习之基于reset实现分布式事务的详细内容。
