Why do you choose TCC
Our service call uses Dubbo and is a sensitive operation with large funds. TCC is the most appropriate if we do not change the original call mode.
Second, the industry’s mainstream TCC framework
We primarily surveyed TCC-Trancsactional for use, with follow-up studies on the open source Seata(Fescar). Finally, we realized our own TCC framework according to the actual situation.
Seata TCC principle
- The TC creates a global transaction ID and returns it to TM. The global transaction is started and the global transaction ID is incorporated into RootContext(ThreadLocal).
- When the business method to execute is invoked, the TCC Bean is parsed, the TCC Resource is created, and the TC is registered.
- When the business method to execute is invoked, the branch transaction is registered with the TC and incorporated into the management of the global transaction.
- TM initiates a global commit or rollback to the TC.
Shortcomings of Seata TCC
- The network overhead of multiple RPC calls between participants and TCS affects certain performance.
- Currently, only File storage transactions are supported, and the transaction recovery mechanism is incomplete.
- Exception control needs to be controlled by the business itself.
TCC Tracnsactional
TCC Transactional has two facets. Instead of having a single transaction coordinator, TCC Transactional binds the transaction coordinator to the application. This ensures the availability of the transaction coordinator as long as the application is available, and reduces RPC calls between business parties and TCS. It provides a variety of transaction storage methods, transaction recovery capability and operation and maintenance platform, and has been used by many companies.
TCC Transactional also has its limitations. Its exception control mechanism is not perfect and can cause problems when network jitter occurs or the called party goes down.
Third, database model design
The transaction service invokes at least three services, each of which involves changes in funds. The original database model could not well adapt to the design idea of TCC after using TCC. After referring to the design of Ant Financial, we re-optimized the data model of position holding service and expense service.
-
The original database model of the holding service
CREATE TABLE IF NOT EXISTS 'position' (' id 'INT UNSIGNED AUTO_INCREMENT,' amount 'DECIMAL(20,8), -- PRIMARY KEY (' id ')ENGINE=InnoDB DEFAULT CHARSET=utf8;Copy the code
-
After the transformation of the position database model
CREATE TABLE IF NOT EXISTS 'position' (' id 'INT UNSIGNED AUTO_INCREMENT,' amount 'DECIMAL(20,8), -- hold amount 'frozen' DECIMAL(20,8), -- freeze fund PRIMARY KEY (' id '))ENGINE=InnoDB DEFAULT CHARSET=utf8;Copy the code
Concurrency control
-
Try stage
update position set amount=amount - #{money},frozen=frozen + #{money} where id = #{id} and amount > #{money}; Copy the code
Deduct hold, increase frozen amount.
-
Confirm stage
update position set frozen= frozen - #{money} where id = #{id}; Copy the code
Release frozen funds.
-
Cancel stage
update position set amount=amount + #{money} ,frozen= frozen - #{money} where id =#{id} and frozen > #{money}; Copy the code
Increase positions and release frozen funds.
Four, abnormal
1. Empty rollback -try Cancel is not executed
- Try call timeout
- The called feigns death for a short time
2. Idempotent problem
- The network jitter
- Transaction recovery retry multiple times
3. The suspension
- If the try interface times out, perform cancel to recover the try interface
5. Abnormal control
create table tcc_transaction_xxx(
`id` INT UNSIGNED AUTO_INCREMENT,
`app` char(20) comment 'Business module',
`tx_id` varchar(100) not null comment 'Global transaction ID',
`branch_id` varchar(100) not null comment 'Branch transaction ID',
`create_time` datetime not null comment 'Creation time',
`update_time` datetime not null comment 'Update Time',
`content` varbinary(8000) default null comment 'Transaction content',
`status` tinyint not null comment 'Status <>try=0= sent & Confirm =1= Committed & Cancel = Rolled back',
`version` int(11) default 0 comment 'version',
`retried_content` int(11) default 0 comment 'Retry times',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
Copy the code
- Try stage
During the first phase of services, the transaction control table is inserted to check whether status is the second phase. In the second phase of services, an exception is thrown to terminate the first phase.
- Confirm stage
- Cancel stage
Refer to the article
Distributed transaction Seata TCC mode depth resolution | SOFAChannel# 4 live finishing – financial level distributed architecture articles – zhihu zhuanlan.zhihu.com/p/63552935
Seata TCC distributed transaction source analysis – Young Chen, in his article on zhihu zhuanlan.zhihu.com/p/64484721
Seata TCC distributed transaction source analysis – Young Chen, in his article on zhihu zhuanlan.zhihu.com/p/64484721