- Generally in
微服务
development, an interface involves multiple service calls and data modifications in different databases. In order to ensure data consistency, distributed transactions need to be introduced.- Just introduce
单应用
local affairs .@Transactional(rollbackFor = Throwable.class)
- Distributed transactions can
spring cloud alibaba - seata
be implemented using frameworks. After deploying nacos and seata clients,@GlobalTransactional
they can be implemented by declaring the interface.
Seata介绍:是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
– Seata official website documentation
Common distributed transaction solutions:
- seata Alibaba distributed transaction framework
- Message Queue, Reliable Message-》Article
- Saga
- SHAH
Introduction to transaction mode:
- AT mode: It is a non-intrusive distributed transaction solution.
– Phase 1: Seata will intercept the business sql, parse the sql semantics to find the data to be updated by the business sql,数据更新前
save the snapshot before image before update; then execute the business sql to update the data;数据更新后
save it as after images, post-update snapshot, Generate row locks.
– Phase 2: If there is no exception in the interface正常执行
, because the business sql has been submitted in the first phase, the snapshot data and row locks will be deleted after the interface is executed normally, and the data will be completely cleaned; when the interface execution occurs, the data will be异常时
rolled back, executed first脏写校检
, and compared with the current database If the business data is consistent with the after image, the business data can be restored. If dirty writes occur, manual processing is required; when there are no dirty writes, reverse SQL is generated through the before image to restore the data.- TCC mode: It is highly intrusive and implements relevant transaction control logic by itself. There are basically no locks in the whole process and the performance is stronger.
– The transaction initiator executes Try mode in the first phase, commits and executes confirm in the second phase, and rolls back and executes cancel.
Version correspondence –
Download the corresponding version running body, as well as running configuration and table,
such as version 1.4.2
basic configuration https://github.com/seata/seata/tree/1.4.2
running jar https://github.com/seata/seata/tags
Pre-environment: only need to be configured once
- Modify seata-server-1.4.2\conf, file.conf, select the corresponding storage mode, the default file stand-alone mode
records the high-availability db mode here, modify the file.conf file, switch the db mode, and modify the data link information.
- Modify register.conf and configure nacos connection information. (Transaction participants need to communicate with seata); after ensuring that nacos starts normally, modify the script resource directory in the source code, \config-center\config.txt, modify the registration information, configure the storage mode, database connection information, transaction grouping information, and then Run the registration script
nacos-config.sh
to register the information to nacos.
- Import the database information in the resource directory and create the database seata; execute the script\server\db\mysql.sql file
- Run seata-server.bat
to start the cluster:
add the undo_log table in the corresponding library of the service participant; keep the source data before and after execution, script\client\at\db\mysql.sql
-- 对应服务添加 undo_log表
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`context` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime(0) NULL,
`log_modified` datetime(0) NULL,
PRIMARY KEY (`id`) USING BTREE
);
code integration
Parent project dependencies:
<dependencyManagement>
<dependencies>
<!--spring boot 公共版本定义-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud 公共版本定义 通过dependencies完成继承-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Server-side dependencies:
<!-- 客户端调用-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
Service participant yml configuration:
spring:
application:
name: stock-service
cloud:
nacos:
config:
group: DEFAULT_GROUP
server-addr: 127.0.0.1:8848 #nacos服务地址
file-extension: yaml #配置文件类型
#seata 配置
seata:
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
application: seata-server
username: nacos
password: nacos
group: SEATA_GROUP
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
group: SEATA_GROUP
tx-service-group: my_test_tx_group
At the interface, or in service@GlobalTransactional
@GlobalTransactional
@RequestMapping("/add")
public String add(){
Order order = new Order(9,20,0);
orderMapper.insert(order);
String reduct = stockService.reduct(9);
int i=1/0;
return "ok"+reduct;
}
Pre-environment configuration is a bit cumbersome, but you only need to configure it once and then execute the statement annotation to implement distributed transactions.
-
TC (Transaction Coordinator) - The transaction coordinator maintains the status of global and branch transactions and drives global transaction submission or rollback.
-
TM (Transaction Manager) - The transaction manager defines the scope of a global transaction: starts a global transaction, commits or rolls back a global transaction.
-
RM (Resource Manager) - Resource Manager
manages resources for branch transaction processing, talks to TC to register branch transactions and report the status of branch transactions, and drives branch transactions to commit or rollback.
Process analysis, AT mode summary:
1 TC will generate an XID as the number of the global transaction. XID will be propagated in the calling link of microservices to ensure that sub-transactions of multiple microservices are associated together.
2. When entering the interface method, generate an XID; register the transaction participant as a transaction branch of the global transaction. Each transaction is isolated by the XID of the global transaction. If there are multiple distributed transactions @GlobalTransactional, there will be multiple XIDs. Multiple XIDs are used to connect these transaction participants.
global_table
, stores global transaction information.
branch_table
Branch transaction information. Store transaction participants
lock_table
lock table information, purpose: isolation between branch transactions,
undo_log
roll back snapshot data