Cheese with the view of distributed transactions

Transaction refers to all operations within. All operations within a transaction related to the execution into an indivisible unit, either all executed or not executed all. This is the popular understanding of the transaction.

In general, transactions are for the purposes of the database, but in fact is not, for example, a number of message queues RocketMq, kafka, etc. will be involved in the affairs of these components has a special term, called Resource Manager (Resource Manager, namely RM)

Distributed transaction, along with the more widely distributed systems process derived from a new concept, generally refers to the RM on different nodes in the popularity of the micro service today, more and more worthy of being distributed transactions seriously.

Local Services

This article is to introduce a distributed transaction, but to say a distributed transaction, a local transaction is not open around the topic. So what we have here is too fast concepts of local affairs.

ACID

ACID is a transaction must have four characteristics which are:

1. A是指原子性. 是指一个操作必须是一个不可分割的单元, 要么执行要么不执行, 不能存在指执行了一半,另外一半没执行的状态
2. C是指一致性. 是指事务执行前后,系统都处在一个一致性的状态.
3. I是指隔离性. 隔离性是指不同事务之间应该互相隔离,不受影响
4. D是持久性, 表示事务的执行应该是永久性的, 不能因为系统重启或奔溃就丢失
复制代码

Generally, ACID I will lead in another set of concepts: visibility problems and isolation level.

Visibility problem is one of visibility due to operations within a transaction in a further transaction brought. In general, the higher the visibility, the more likely it is problematic.

High to low visibility problems are the following:

1. 读未提交. 一个事务能读到另外一个事务未提交的更改.这是最严重的问题的,未提交的数据都是脏数据.

2. 不可重复读. 所谓的不可重复读是指一个事务第一次读某条记录
和第二次读同一条记录时会读到不一样的内容.
原因是该事务在这两次读之间, 有另外一个事务更新了这条记录,并且提交了.

3. 幻读. 所谓幻读是指一个事务在两次读同一份数
据时, 第一次和第二次读到的数量不一样. 原因是该事务在这两次读之间,
有另外一个事务新增/删除了记录, 并提交了.


可以看到, 其实不可重复读和幻读都是由于另外一个事务更改了数据造成的.
两者的差别是另外一个事务的操作是update还是insert/delete
复制代码

Isolation levels and visibility problems are echoed, is to get rid of the visibility problems in isolation of each class

Isolation levels are the following:

1. 读未提交. 这是最低级别的隔离等级, 很明显,什么可见性问题都没解决.
2. 读已提交. 解决了"读未提交"的问题
3. 可重复读. 解决"不可重复读"的问题
4. 串行化, 解决了"幻读"的问题.
复制代码

Of course, the lower the throughput of the higher level of isolation means that the processing of the data.

Transactions in mysql

In mysql, may be implemented with the transaction begin, commit, rollback three instructions.

1. begin用来开始一个事务.
2. commit 用来提交一个事务
3. rollback用来回滚一个事务
复制代码

mysql transaction is submitted automatically by default. You can use

set autocommit = 0
或
set autocommit = 1
复制代码

To turn off / turn on automatic submission.

It is worth mentioning that, mysql default isolation level is "repeatable read" but high version of the innodb (mysl5.7) actually lock through the gap reached a "serialization" of the standard.

Transactions in spring

spring is to support transactional operations, then, but the transaction spring operation in fact is just a proxy, are ultimately dependent on database begin, commit, rollback implemented.

Programmatic transaction

Programmatic transaction manually by means transactionTemplate TransactionManager control and commit and rollback transaction.

Programmatic transaction with respect to the declarative transaction, a higher degree of flexibility, for example, can be committed or rolled back against a section of code.

Declarative transaction (Acting)

Declarative transaction is popular for comment affairs, by adding the spring of @Transactional annotation to declare a method or class up affairs, hence the name "declarative transactions."

@Transactional commonly used parameters are:

1. propagation, 指定事务的传播等级
2. isolation, 指定隔离等级
3. norollback for, 指定不回滚事务的异常
4. rollback for, 指定需要回滚事务的异常
5. timeout, 指定事务的超时时间

复制代码

Principle declarative transaction is dynamic proxy and AOP, is simply add begin, commit, rollback logic before and after the implementation of specific methods.

The greatest advantage is a simple declarative transaction, low invasive code. Drawback is the particle size corresponding to not controlled, the smallest particle size are to be added to the method.

The spread of the transaction (nested transactions)

Spread affairs colloquially speaking, it is the call chain multiple method, if it comes to matters of nesting, spring should be handled.

This concept is also the principle of declarative transactions which arise out of the Principle Declarative transaction is made before and after the dynamic proxy method plus open in the transaction and commit logical transaction.

Consider the following scenario of:

@Transational
public void A(){
    B();
    // do something
}
@Transational
public void B(){
    //dosomething
    int a = 1/0
}
复制代码

The above two methods are declared open transactions, it is clear that B will throw an exception, the transaction B will be rolled back. Then A will also be rolled back yet. This requires a propagation mechanism to resolve the matters.

spring propagation mechanisms transaction a total of 7:

1. propagation_require. 默认的传播类型. 表示当前方法需要再一个事务中执行, 如果没有开启事务, 则需要开启一个

2. propagation_support. 表示当前方法不需要事务, 但是如果事务存在,则在事务中执行

3. propagation_mandatory. 表示当前方法必须要在事务中执行, 如果不存在,则抛出异常.

4. propagation_requireNew. 表示当前方法需要在新的事务中执行.当前方法执行时, 如果已经存在一个事务, 则先挂起该事务

5. propagation_not_support. 表示当前方法不支持事务, 如果已经存在事务, 那就先挂起该事务.

6. propagation_never. 表示当前方法不应该在事务中执行, 如果存在事务, 则抛异常.

7. propagation_nested. 如果存在嵌套的事务, 那么各个方法在各自独立的方法里面提交和回滚.
复制代码

Distributed Transaction

DTP, XA and JTA

DTP model

DTP (Distributed Transaction Processing) is a model of distributed transaction x / open organization put forward.

A DTP model comprises at least the following three elements:

1. AP, 应用程序,用于定义事务开始和结束的边界. 说人话就是我们开启事务的代码所以的应用.
2. RM, 资源管理器. 理论上一切支持持久化的数据库资源都可以是一个资源管理器.
3. TM, 事务管理器, 负责对事务进行协调,监控. 并负责事务的提交和回滚.

复制代码
XA specification

XA is x / open specification proposed by the distributed transaction, it is nothing to do with language.

RM XA specification defines the interface and interact, for example, TM TM RM can be managed via the following interfaces:

  1. xa_open和xa_close, 用于跟RM建立连接
  2. xa_star和xa_end, 开始和结束一个事务
  3. xa_prepare, xa_commit和xa_rollback, 用于预提交, 提交和回滚一个事务
  3. xa_recover 用于回滚一个预提交的事务
复制代码
JTA specification

JTA specification is considered to be the XA specification java language version of the specification.

JTA defines a set of distributed transaction-related interfaces:

1. javax.transaction.Status: 定义了事务的状态,例如prepare, commit rollback等等等
2. javax.transaction.Synchronization:同步
3. javax.transaction.Transaction:事务
4. javax.transaction.TransactionManager:事务管理器
5. javax.transaction.UserTransaction:用于声明一个分布式事务
6. javax.transaction.TransactionSynchronizationRegistry:事务同步注册
7. javax.transaction.xa.XAResource:定义RM提供给TM操作的接口
8. javax.transaction.xa.Xid:事务id
复制代码

More different interface is implemented by different roles (RM, RM, etc.).

Two-phase commit protocol (2PC)

Two-phase commit protocol is the easiest solution for distributed transactions. It is divided into a transaction request commit and commit / rollback of two phases.

The first stage is the stage of the request, whether submitted by the coordinator to ask it of RM transactions. If you can submit the reply YES, otherwise return NO.

The second stage is the submission stage, the coordinator to decide whether the distributed transaction may be submitted. If all of the RM have replied YES, you can submit, or roll back the transaction based on the response of all the RM.

Two-phase commit protocol idea is simple, but it has a lot of problems.

  1. Coordinator of a single point
  2. The first phase of blocking problems
  3. The second stage due to network problems, RM does not receive commit / rollback instructions cause data inconsistencies.

Three-phase commit (3PC)

Three-phase commit is to solve the two-stage algorithm existing problems and to submit it to the transaction divided into three stages:

 1. cancommit阶段, 和2PC中的请求阶段类似
 2. precommit阶段. 如果cancommit阶段不是全部响应YES或者有RM超时, 那么回滚整个事务. 
 否则, 发送precommit指令, 让各个RM执行事务操作,执行完后响应ACK.
 3. docommit阶段.如果precommit阶段由RM没有响应ACK或者超时, 那么回滚整个事务.
 否则发送docommit指令, 让各个RM真正提交事务.
复制代码

TCC

TCC refers to the try-comfirm-cancel. Is one kind of fire in these years, flexible solution for distributed transactions.

The so-called "flexible" is aimed 2PC and 3PC such as "rigid affairs" in terms of flexible transaction is no longer blind pursuit of strong consistency, only requires eventual consistency.

TCC to a distributed transaction is split into the following three steps:

1. try阶段. 各个事务参与者检查业务一致性, 预留系统资源.例如锁定库存
2. comfirm阶段. 事务参与者使用try阶段预留的资源,执行业务操作.
3. cancel阶段. 如果try阶段任意一个事务参与者try失败, 则做cancel操作. cancel包括释放资源和反向补偿
复制代码

In fact, a closer look, TCC is just with request-commit-rollback 2PC in a one to one. From this point of view, the nature of the TCC is a solution 2PC thought.

In TCC there are two concepts, the main business service and business service.

Main business services can be understood as a popular service that initiated the transaction. For example a purchase of service that were calling service inventory and order services. So purchase the service can be seen as the main business services.

Correspondingly, the above mentioned "Inventory service" and "Order Service" is the business service.

Why we must first distinguish between the two services it because their duties are not the same?:

1. 从业务服务必须要提供try, comfirm, cancel方法.
2. 主业务服务需要记录事务日志, 并在事务管理器的协调下, 适当地调用从业务服务的tcc三个方法.
复制代码

TCC model as shown below:

image

Pictures from www.tianshouzhi.com/api/tutoria... , while also strongly recommend this blog, benefit.

message queue

The use of message queues to achieve eventual consistency is another idea of ​​a flexible distributed transactions. Its main idea to complete a distributed transaction by asynchronous message queues, combined with regular tasks done retry and compensation, when necessary, require human intervention.

Summarize speaking, a total of "best effort," which "local message table" and "MQ transaction messages" Three Kinds of thought.

We do our best to inform

Do our best to inform that the initiative to inform parties will make every effort to deal with the results of notification to the recipient, if the notification fails, it will do the most X retries if ultimately failed, the active partner provides an interface to query, you can take the initiative by the recipient Inquire.

This idea is simple, in fact, the application is more typical are:

1. 运营商短信发送状态回传
2. 微信和支付宝支付状态回传
复制代码
Local news list

As the name suggests, it is to use a local news local database table maintenance intermediate state of completion of the transaction. In the process of distributed transaction execution, the parties to the transaction participants to update the status message table after the completion of operations, the gradual completion of the transaction as a whole.

In the case of abnormality, the timing detection by the timing schedule table unfinished message transactions, initiating the retry timing scheduling solutions see six kinds of gesture execution timing of the task in java

If one party ultimately failed to complete the transaction operations, by manual intervention to compensate.

image

If a picture above:

  1. 生产者先写本地消息表和业务数据, 用本地事务保证成功.再发送MQ消息.
  
  2. 消费者消费数据,同样是执行本地事务. 成功后更新本地消息表的状态. 失败怎么办呢? 可以发送消息给生产者进行回滚, 但是那样复杂度
  就高了(要求生产者也要实现TCC, 那就还不如用TCC了). 所以更现实的方案是重现+人工补偿
  
 3. 生产者可能会写业务数据成功, 但是发送MQ消息失败, 这个时候本地消息表还是会有对应未完成的事务, 那么定时任务会扫描出来, 重试.最终还是能完成整个分布事务.
 
复制代码

Of course, the figure is not hundred percent perfect but watch the local news is more of an idea, specific implementations may vary, but also combined with specific business scenarios and business requirements to achieve.

MQ transaction message

Table of local news programs put forward at the time have not yet achieved universal MQ message of affairs. But now, whether or rocketMQ kafka are beginning to support the transaction message.

With the transaction message, in fact, the work of local tables and regular tasks on the MQ transaction mechanism to complete.

E.g. www.tianshouzhi.com/api/tutoria... program which introduced.

Distributed Transaction Framework

In practical applications, the scene appeared distributed transactions can be summarized into two or to purchase a service, for example, the scene of both the distributed transaction might be:

  1. The first, with a plurality of service operation RM

image

  1. The second, a service call multiple services via RPC, indirect operating more than RM

image

In the service of micro popular today, by business sub-library should be a basic principle of most companies to build infrastructure, so this point of view, looks like the second scenario is more realistic.

Of course, the first scenario certainly still exist. For example above, "local news sheet" solution, there is need to interact with the same service in more than RM.

In fact, open source framework for distributed transaction market is also a lot of, for example tcc-transactio and so, here we take a look at these two atomikos and seata

atomikos

atomikos is a very well-known open source framework for distributed transactions. It has to achieve JTA / XA specification, there are implementation mechanisms TCC, the former is free and open source, which is a commercial paid version.

Here is what you achieve JTA / XA specification.

Speaking of that section in the above JTA JTA specification defines a set of interfaces, those interfaces are different roles to achieve the atomikos role is a transaction manager that implements the interfaces are mainly:

 1. javax.transaction.UserTransaction
   对应的实现是com.atomikos.icatch.jta.UserTransactionImp,用户只需要直接操作这个类就是实现一个JTA分布式事务

 2. javax.transaction.TransactionManager
   对应的实现是com.atomikos.icatch.jta.UserTransactionManager, atomikos使用这个实现类来对事务进行管理

 3. javax.transaction.Transaction
    对应的实现是com.atomikos.icatch.jta.TransactionImp
复制代码

Examples of simple applications atomikos (or from www.tianshouzhi.com/api/tutoria... ):

  1. The introduction of dependence
<dependency>
   <groupId>com.atomikos</groupId>
   <artifactId>transactions-jdbc</artifactId>
   <version>4.0.6</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.39</version>
</dependency>
复制代码
  1. demo examples
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.jdbc.AtomikosDataSourceBean;

import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class AtomikosExample {

  private static AtomikosDataSourceBean createAtomikosDataSourceBean(String dbName) {
     // 连接池基本属性
     Properties p = new Properties();
     p.setProperty("url", "jdbc:mysql://localhost:3306/" + dbName);
     p.setProperty("user", "root");
     p.setProperty("password", "your password");

     // 使用AtomikosDataSourceBean封装com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
     AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
     //atomikos要求为每个AtomikosDataSourceBean名称,为了方便记忆,这里设置为和dbName相同
     ds.setUniqueResourceName(dbName);
     ds.setXaDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
     ds.setXaProperties(p);
     return ds;
  }

  public static void main(String[] args) {

     AtomikosDataSourceBean ds1 = createAtomikosDataSourceBean("db_user");
     AtomikosDataSourceBean ds2 = createAtomikosDataSourceBean("db_account");

     Connection conn1 = null;
     Connection conn2 = null;
     PreparedStatement ps1 = null;
     PreparedStatement ps2 = null;

     UserTransaction userTransaction = new UserTransactionImp();
     try {
        // 开启事务
        userTransaction.begin();

        // 执行db1上的sql
        conn1 = ds1.getConnection();
        ps1 = conn1.prepareStatement("INSERT into user(name) VALUES (?)", Statement.RETURN_GENERATED_KEYS);
        ps1.setString(1, "tianshouzhi");
        ps1.executeUpdate();
        ResultSet generatedKeys = ps1.getGeneratedKeys();
        int userId = -1;
        while (generatedKeys.next()) {
           userId = generatedKeys.getInt(1);// 获得自动生成的userId
        }

        // 模拟异常 ,直接进入catch代码块,2个都不会提交
//        int i=1/0;

        // 执行db2上的sql
        conn2 = ds2.getConnection();
        ps2 = conn2.prepareStatement("INSERT into account(user_id,money) VALUES (?,?)");
        ps2.setInt(1, userId);
        ps2.setDouble(2, 10000000);
        ps2.executeUpdate();

        // 两阶段提交
        userTransaction.commit();
     } catch (Exception e) {
        try {
           e.printStackTrace();
           userTransaction.rollback();
        } catch (SystemException e1) {
           e1.printStackTrace();
        }
     } finally {
        try {
           ps1.close();
           ps2.close();
           conn1.close();
           conn2.close();
           ds1.close();
           ds2.close();
        } catch (Exception ignore) {
        }
     }
  }
}
复制代码

Obviously, this example is part of a distributed transaction scenario 1, so if there is a scene of a distributed transaction, then the direct use atomikos can, straightforward and efficient.

But then again, the actual scene of distributed transactions more or belong to scene 2. Obviously simple JTA transaction is not distributed transaction processing scenario 2. Distributed Transaction 2 next scene, you will need as TCC or message queues affairs flexible solutions to achieve.

SEAT

Seata meaning that after Fescar (TXC / GTC / FESCAR) and tcc-transaction integration of open source distributed transaction landing a solution framework to achieve the AT, TCC, SAGA three models, much dominate the political arena.

Official website address is seata.io/zh-cn/docs/... , relatively aspects of the document is not perfect, but still enough as to understand. Here is a brief introduction.

the term

TC - affairs coordinator maintains global state of affairs and branch, driving the global transaction is committed or rolled back.

TM - Transaction Manager to define a global transaction scope: Start the global transaction, the global transaction is committed or rolled back.

RM - Resource Explorer Administration branch of the transaction, talk to register and report the transaction branch branch of state affairs and TC, and drives the branch transaction is committed or rolled back.

AT mode

AT namely Automatic Transaction, the so-called AUTO, indicate that this business model is non-invasive and does not require the transformation of business on the business but there are requirements:

1. 基于支持本地 ACID 事务的关系型数据库。
2. Java 应用,通过 JDBC 访问数据库。
复制代码

FIG overall AT mode logic is as follows:

image

2PC is also used in AT mode of thought, joined the mechanism of compensation, the compensation mechanism inside with innodb undo log similar.

undo log is actually a reverse compensation, such as insert statements, transaction rollback, it will perform a corresponding delete statement

With a large vernacular translation bit mode (I understand) is:

1. 第1阶段, 先生成undo日志, undo日志和业务的操作在本地事务中一并提交
2. 第2阶段, 在TC的协调下, 如果可以提交则迅速提交. 需要回滚时根据回滚日志做反向补偿.
复制代码

Of course, the specific application is not so simple, more references official website

TCC mode

TCC TCC model is the idea described above, SEATA of tcc mode as shown below:

image

In fact, with TCC mode AT mode is similar, but also a 2PC of Evo, in coordination with the transaction coordinator (TC), the plurality of sub-transaction commit and rollback.

The difference is that, AT mode is to roll back the database to compensate the resource level (rollback log), while TCC is to call custom logic rollback (rollback code logic).

SAGA mode

saga is a long transaction solutions in Saga mode, a business process each participant to submit local affairs, when one participant fails to compensate the participants already appeared successful, a stage and two-stage forward service compensation business development services are realized

image

While the saga of the idea put forward in 1987, but the model is seata the saga of August this year, it was officially supported. I also understand it's not deep enough, so I do not. look to the trespass

to sum up

Distributed systems has never been a simple concept, especially distributed transaction in a distributed system.

Perhaps the idea of ​​distributed transactions is relatively simple, but realized it does have a lot of details and difficulties we need to pay attention to and overcome. It is therefore most companies will have to do it according to their actual business practice different, not completely to copy the idea.

This is reflected in the other side it is that now the market really does not have a complete distributed solutions, allow us to copy it. Ali seata open soon, too, hope that one day, it really can dominate the political arena, the real We can solve the problem of distributed transactions disposable one-stop shop

Quote

www.tianshouzhi.com/api/tutoria…

seata.io/zh-cn/docs/…

Guess you like

Origin juejin.im/post/5dd8c8f56fb9a07ac6041e98