Seata: Simple Extensible Autonomous Transaction Architecture

TC — Global Exclusive Write Lock Implementation Solution

First, take a look at the portal for the TC module to interact with the external. The following figure shows the main function of the TC module:

/**
* When a branch transaction is registered, the system obtains the global lock resources of the branch transaction.
*/
@Override
protected void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response,
RpcContext rpcContext) throws TransactionException {
response.setTransactionId(request.getTransactionId());
response.setBranchId(core.branchRegister(request.getBranchType(), request.getResourceId(), rpcContext.getClientId(),
XID.generateXID(request.getTransactionId()), request.getLockKey()));
}
/**
* Check whether the global lock can be obtained.
*/
@Override
protected void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response, RpcContext rpcContext)
throws TransactionException {
response.setLockable(core.lockQuery(request.getBranchType(), request.getResourceId(),
XID.generateXID(request.getTransactionId()), request.getLockKey()));
}
/**
* When a global transaction is committed, records occupied by locks of all branch transactions under the global transaction are released.
*/
@Override
protected void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response, RpcContext rpcContext)
throws TransactionException {
response.setGlobalStatus(core.commit(XID.generateXID(request.getTransactionId())));
}
private static final ConcurrentHashMap<String, ConcurrentHashMap<String, ConcurrentHashMap<Integer, Map<String, Long>>>> LOCK_MAP = new ConcurrentHashMap<~>();

Why Is Concurrenthashmap Used in the First Half of the Lock Structure, and Hashmap Used in the Second Half?

ConcurrentHashMap is used in the first half to support better concurrent processing. The question is, why not use ConcurrentHashMap directly in the second half, but HashMap instead? The possible reason is that the second half of the structure needs to determine whether the current global transaction occupies the lock resources corresponding to the primary key, which is a composite operation. Even if ConcurrentHashMap is adopted, it is still inevitable to use Synchronized lock for determination, so it is better to directly use the more lightweight HashMap.

Why Does Branchsession Store the Lock Resources Occupied by the Branch Transaction?

This is relatively simple to understand. The lock records occupied by branch transactions are not reflected in the entire lock structure. Thus, how can a branch transaction release the occupied lock resources when a global transaction is committed? Therefore, the lock resources occupied by branch transactions are stored in BranchSession.

RM — Global Exclusive Write Lock Usage

In the RM module, two functions of the global lock in the TC module are mainly used. One is to check whether the global lock can be obtained, and the other is to register a branch transaction to occupy the global lock. The release of the global lock is independent of RM and is automatically released by the TC module when the global transaction is committed. Before registering a branch transaction, the global lock status check logic is performed to ensure that lock conflicts will not occur in the branch registration

  1. Execute the Select … For update statement, so that the local transaction occupies the row lock corresponding to the database, while other local transactions can not preempt the row lock of the local database, and thus will not preempt the global lock.
  2. Check whether the global lock can be obtained cyclically. The global lock may be obtained by a global transaction earlier than the current global transaction, so it is necessary to wait for the previous global transaction to release the global lock resource. If the check shows that the global lock can be obtained, then as described in step 1, other local transactions will not obtain the global lock before the current local transaction ends, thus ensuring that the registration of branch transactions before the current local transaction is committed will not fail due to the global lock conflict.

Summary

This article details the global exclusive write lock implemented by Seata to achieve write isolation at the Read Uncommitted isolation level, including the implementation principle of the global exclusive write lock in the TC module, and the logic of using the global exclusive write lock in the RM module. During the process of learning the source code, two issues are left behind:

  1. The global exclusive write lock data structure is stored in the memory. What if the server is restarted or goes down? And what is the high availability solution of the TC module?
  2. What if a lock conflict occurs between a global transaction managed by Seata and a local transaction not managed by Seata? The specific problem is as follows. The question is: How does global transaction A roll back?

Reference

https://www.alibabacloud.com/blog/seata-simple-extensible-autonomous-transaction-architecture_594853?spm=a2c41.12952834.0.0

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com