All Projects → windawake → laravel-reset-transaction

windawake / laravel-reset-transaction

Licence: MIT license
distributed transaction for call remote api service

Programming Languages

PHP
23972 projects - #3 most used programming language

Projects that are alternatives of or similar to laravel-reset-transaction

mysql-interview-questions
SQL Basics
Stars: ✭ 202 (+405%)
Mutual labels:  transaction
mxfactorial
a payment application intended for deployment by the united states treasury
Stars: ✭ 36 (-10%)
Mutual labels:  transaction
LocalTransactionTableTest
利用rabbitmq做消息队列,通过本地消息事务表序列化消息,通过定时轮训保证消息强行落地,最终达到数据最终一致性
Stars: ✭ 19 (-52.5%)
Mutual labels:  transaction
leptin
🔗 Leptin is a PoW blockchain completely built in Nodejs.
Stars: ✭ 57 (+42.5%)
Mutual labels:  transaction
Transactional-NTFS-TxF-.NET
Transactional NTFS (TxF) Library .NET is a small library .Net (C#) allows to use transactions on NTFS FileSystem (Transactional NTFS (TxF))
Stars: ✭ 20 (-50%)
Mutual labels:  transaction
orchestrate-node
This Orchestrate library provides convenient access to the Orchestrate API from applications written in server-side NodeJS
Stars: ✭ 19 (-52.5%)
Mutual labels:  transaction
kotlin-coroutines-jdbc
A library for interacting with blocking JDBC drivers using Kotlin Coroutines.
Stars: ✭ 40 (+0%)
Mutual labels:  transaction
indexeddb-orm
Indexed DB ORM
Stars: ✭ 53 (+32.5%)
Mutual labels:  transaction
OGMNeo
[No Maintenance] Neo4j nodeJS OGM(object-graph mapping) abstraction layer
Stars: ✭ 54 (+35%)
Mutual labels:  transaction
trans-dsl
a transaction model framework, seems simple but powerful
Stars: ✭ 64 (+60%)
Mutual labels:  transaction
MySQL-cheatsheet
Cheatsheet for MySQL
Stars: ✭ 43 (+7.5%)
Mutual labels:  transaction
kunlun-storage
Kunlun-storage is the storage component for KunlunBase. It's developed based on percona-mysql-8.0.x and contains exclusive features used by KunlunBase, performance enhancements and XA transaction crash safety enhancements without which MySQL would not be able to execute XA transactions reliably under error conditions such as power outage, proces…
Stars: ✭ 2 (-95%)
Mutual labels:  transaction
KuiBaDB
Another OLAP database
Stars: ✭ 297 (+642.5%)
Mutual labels:  transaction
ex operation
A library for making domain operations in Elixir
Stars: ✭ 33 (-17.5%)
Mutual labels:  transaction
ddal
DDAL(Distributed Data Access Layer) is a simple solution to access database shard.
Stars: ✭ 33 (-17.5%)
Mutual labels:  transaction
simple-mpesa
A simple example of how MPESA works. Works with all 3 types of customers i.e. Agents, Merchants and Subscribers. Allows you to configure a tariff and apply it to transactions. The project follows DDD principles.
Stars: ✭ 31 (-22.5%)
Mutual labels:  transaction
SimpleCoin
A simple cryptocurrency application for educational purposes only.
Stars: ✭ 13 (-67.5%)
Mutual labels:  transaction
arweave-python-client
This client allows you to integrate your python apps with the Arweave network allowing you to perform wallet operations and transactions
Stars: ✭ 87 (+117.5%)
Mutual labels:  transaction
saga-pattern-nodejs-aws
An implementation of Saga pattern for distributed transactions with NodeJS and AWS
Stars: ✭ 34 (-15%)
Mutual labels:  transaction
Apriori-and-Eclat-Frequent-Itemset-Mining
Implementation of the Apriori and Eclat algorithms, two of the best-known basic algorithms for mining frequent item sets in a set of transactions, implementation in Python.
Stars: ✭ 36 (-10%)
Mutual labels:  transaction

laravel-reset-transaction

中文文档

RT (reset transaction) mode can be as distributed transaction for call remote api service

Overview

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

## Composer2 version must be used
composer require windawake/laravel-reset-transaction dev-master

First create order, storage, account 3 mysql database instances, 3 controllers, 3 models, add testsuite Transaction to phpunit.xml, and then start the web server. These operations only need to execute the following commands to complete all

php artisan resetTransact:create-examples && php artisan serve --host=0.0.0.0 --port=8000

Open another terminal and start the web server with port 8001

php artisan serve --host=0.0.0.0 --port=8001

Finally run the test script ./vendor/bin/phpunit --testsuite=Transaction --filter=ServiceTestThe running results are shown below, and the 3 examples have passed the test.

DESKTOP:/web/linux/php/laravel/laravel62# ./vendor/bin/phpunit --testsuite=Transaction --filter=ServiceTest
Time: 219 ms, Memory: 22.00 MB

OK (3 tests, 12 assertions)

Feature

  1. Out of the box, no need to refactor the code of the original project, consistent with the mysql transaction writing, simple and easy to use.
  2. Comply with the two-stage commit protocol, which is a strong consistency transaction. Under high concurrency, it supports the isolation level of read committed transactions, and the data consistency is 100% close to mysql xa.
  3. Since the transaction is split into multiple and become several small transactions, the stress test finds that there are fewer deadlocks than mysql ordinary transactions.
  4. Support distributed transaction nesting, consistent with savepoint.
  5. Support to avoid the problem of dirty data caused by the concurrency of different business codes.
  6. The service-oriented interface of the http protocol is supported by default. If you want to support other protocols, you need to rewrite the middleware.
  7. Support for nested distributed transactions of sub-services (world's first).
  8. Support services, mixed nesting of local transactions and distributed transactions (the world's first)
  9. Support 3 retries over time, repeated requests to ensure idempotence
  10. Support go, java language (under development)

Principle

You will know the operation of archiving and reading files after watching the movie "Edge of Tomorrow". This distributed transaction component imitates the principle of the "Edge of Tomorrow" movie. Reset means to reset, that is, read the file at the beginning of each request for the basic service, and then continue the subsequent operations. At the end, all operations are rolled back and archived, and finally One step commit successfully executes all the archives. The whole process is to comply with the two-stage submission agreement, first prepare, and finally commit.

Taking the scenario where user A transfers 100 yuan to user B's China Merchants Bank account with a China Merchants Bank card as an example, the following flowchart is drawn. After the reset distributed transaction is turned on in the right picture, there are 4 more requests than the left picture. What request 4 does is what was done before request 1-3, and then come back to the original point and start again, finally submit the transaction, and end the transfer process.

Support sub-service nested distributed transaction (world's first)

A world-class problem: A service commit->B service rollback->C service commit->D service commit sql. In this scenario, ABCD are all different databases. How can I make A service submit B service and roll back? What about all operations of the C service and D service?

Neither seata nor go-dtm can solve this problem. The key point to solve the problem is that the C service and D service must be submitted falsely, and cannot be submitted truly. If they are submitted, they will be unable to recover.

What are the benefits of implementing nested distributed transactions that support sub-services? You can make A service a service of others, and it can be nested in any layer of the link arbitrarily. Breaking the previous shackles: Service A must be a root service, and if Service A is to become a sub-service, the code must be changed. If the RT mode is used, service A can become someone else's service without modifying the code.

How to use

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

<?php

namespace Tests\Transaction;

use App\Models\ResetAccountModel;
use Tests\TestCase;
use Illuminate\Support\Facades\DB;
use App\Models\ResetOrderModel;
use App\Models\ResetStorageModel;
use GuzzleHttp\Client;
use Laravel\ResetTransaction\Facades\RT;

class ServiceTest extends TestCase
{
    private $baseUri = 'http://127.0.0.1:8000';
    /**
     * @var \GuzzleHttp\Client
     */
    private $client;

    protected function setUp(): void
    {
        parent::setUp();
        DB::setDefaultConnection('service_order'); //默认是订单服务
        $this->client = new Client([
            'base_uri' => $this->baseUri,
            'timeout' => 60,
        ]);
	$requestId = session_create_id();
	session()->put('rt_request_id', $requestId);
    }

    public function testCreateOrderWithCommit()
    {
        $orderCount1 = ResetOrderModel::count();
        $storageItem1 = ResetStorageModel::find(1);
        $accountItem1 = ResetAccountModel::find(1);
	// 开启RT模式分布式事务
        $transactId = RT::beginTransaction();
        $orderNo = rand(1000, 9999); // 随机订单号
        $stockQty = 2; // 占用2个库存数量
        $amount = 20.55; // 订单总金额20.55元

        ResetOrderModel::create([
            'order_no' => $orderNo,
            'stock_qty' => $stockQty,
            'amount' => $amount
        ]);
        // 请求库存服务,减库存
	$requestId = session_create_id();
        $response = $this->client->put('/api/resetStorage/1', [
            'json' => [
                'decr_stock_qty' => $stockQty
            ],
            'headers' => [
                'rt_request_id' => $requestId,
                'rt_transact_id' => $transactId,
            ]
        ]);
        $resArr1 = $this->responseToArray($response);
        $this->assertTrue($resArr1['result'] == 1, 'lack of stock'); //返回值是1,说明操作成功
        // 请求账户服务,减金额
	$requestId = session_create_id();
        $response = $this->client->put('/api/resetAccount/1', [
            'json' => [
                'decr_amount' => $amount
            ],
            'headers' => [
                'rt_request_id' => $requestId,
                'rt_transact_id' => $transactId,
            ]
        ]);
        $resArr2 = $this->responseToArray($response);
        $this->assertTrue($resArr2['result'] == 1, 'not enough money'); //返回值是1,说明操作成功
	// 提交RT模式分布式事务
        RT::commit();

        $orderCount2 = ResetOrderModel::count();
        $storageItem2 = ResetStorageModel::find(1);
        $accountItem2 = ResetAccountModel::find(1);

        $this->assertTrue(($orderCount1 + 1) == $orderCount2); //事务内创建了一个订单
        $this->assertTrue(($storageItem1->stock_qty - $stockQty) == $storageItem2->stock_qty); //事务内创建订单后需要扣减库存
        $this->assertTrue(($accountItem1->amount - $amount) == $accountItem2->amount); //事务内创建订单后需要扣减账户金额
    }

    private function responseToArray($response)
    {
        $contents = $response->getBody()->getContents();
        return json_decode($contents, true);
    }
}

Contact

Scan code into wechat group. I hope that more friends will learn from each other and study the knowledge of distributed transactions together.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].