当前位置:网站首页>Seata implementation of sharing JDBC distributed transaction
Seata implementation of sharing JDBC distributed transaction
2022-06-28 18:30:00 【In a flash】
1、 Implementation mechanism
Sharing-JDBC combination Seata Of AT Pattern implements distributed transactions , The implementation mechanism is as follows :
1.1 Submission phase
AT The pattern is Seata Default mode , Meet the two-phase submission agreement :
- A stage : Business data and rollback logging are committed in the same local transaction , Release local locks and connection resources .
- Two stages :
- Submit asynchronized , Complete... Very quickly .
- Rollback is compensated by a phase of rollback log .
1.2 Implementation logic

A stage :
1、 analysis SQL, Get the executed SQL Statement information ;
2、 According to the condition information obtained from the analysis , Execute query statement , get data , Generate the front image ;
3、 perform SQL sentence , And query the data according to the primary key in the front image , Post generation mirror ;
4、 Mirror the data and business before and after SQL Related information forms a rollback log record , Insert into UNDO_LOG In the table ;
5、 Before committing a transaction , towards TC Register branch transactions , And obtain the global lock according to the primary key value ;
6、 Commit local transaction , Including business SQL、UNDO_LOG The log generated SQL;
7、 Escalate the results of the local transaction commit to TC.
explain : The front and back mirror image is essentially a json strand , Recorded sql Field information in the statement , such as :
"beforeImage": {
"rows": [{
"fields": [{
"name": "id",
"type": 4,
"value": 1
}]
}],
"tableName": "product"
}
Second order - Transaction submission
1、 Branch received TC Transaction commit request for , Submit successfully , And asynchronously delete global locks and UNDO LOG Record ;
Second order - Transaction rollback
1、 adopt XID and Branch ID Find the corresponding UNDO LOG Record ;
2、 take UNDO LOG The rear mirror in is compared with the current data , Verify whether the data has been tampered with by a third party ;
3、 according to UNDO LOG Front image and business in SQL Generates and executes a rollback statement ;
4、 Commit local transaction , Report the result of branch transaction rollback to TC;
1.3 Advantages and disadvantages
- advantage :
- Complete the direct commit transaction in one phase , Release database resources , Good performance .
- Use global lock to realize read-write isolation .
- No code intrusion , The framework automatically completes rollback and commit .
- shortcoming :
- Between the two stages is a soft state , There is no guarantee of strong data consistency , Only data Final consistency .
- Need extra maintenance
undo_logsurface .
2、 Code implementation
Create two SpringBoot engineering , Respectively storage-service And order-service, Simulation from on order-service New orders in the service , And then call storage-service Service new inventory deduction record ; Create two databases respectively , Different services connect to different databases , And realize the configuration of sub table ;
2.1 Create table statement
-- Database name : sharding-tx-order.sql
-- The order sheet
CREATE TABLE `tb_order_1`
(
`id` int(11) NOT NULL COMMENT ' Primary key ',
`count` int(11) NULL DEFAULT 0 COMMENT ' Order quantity ',
`money` int(11) NULL DEFAULT 0 COMMENT ' amount of money ',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
CREATE TABLE `tb_order_2`
(
`id` int(11) NOT NULL COMMENT ' Primary key ',
`count` int(11) NULL DEFAULT 0 COMMENT ' Order quantity ',
`money` int(11) NULL DEFAULT 0 COMMENT ' amount of money ',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
CREATE TABLE `tb_order_3`
(
`id` int(11) NOT NULL COMMENT ' Primary key ',
`count` int(11) NULL DEFAULT 0 COMMENT ' Order quantity ',
`money` int(11) NULL DEFAULT 0 COMMENT ' amount of money ',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
-- undo_log surface
CREATE TABLE `undo_log`
(
`branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id',
`xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'global transaction id',
`context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` longblob NOT NULL COMMENT 'rollback info',
`log_status` int(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` datetime(6) NOT NULL COMMENT 'create datetime',
`log_modified` datetime(6) NOT NULL COMMENT 'modify datetime',
UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'AT transaction mode undo table' ROW_FORMAT = Compact;
-- Database name : sharding-tx-storage.sql
-- An inventory statement
CREATE TABLE `tb_storage_1`
(
`id` int(11) NOT NULL COMMENT ' Primary key ',
`order_id` int(11) NOT NULL COMMENT ' Order ID',
`count` int(11) NOT NULL DEFAULT 0 COMMENT ' stock ',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
-- An inventory statement
CREATE TABLE `tb_storage_2`
(
`id` int(11) NOT NULL COMMENT ' Primary key ',
`order_id` int(11) NOT NULL COMMENT ' Order ID',
`count` int(11) NOT NULL DEFAULT 0 COMMENT ' stock ',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
-- An inventory statement
CREATE TABLE `tb_storage_3`
(
`id` int(11) NOT NULL COMMENT ' Primary key ',
`order_id` int(11) NOT NULL COMMENT ' Order ID',
`count` int(11) NOT NULL DEFAULT 0 COMMENT ' stock ',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;
-- undo_log surface
CREATE TABLE `undo_log`
(
`branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id',
`xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'global transaction id',
`context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` longblob NOT NULL COMMENT 'rollback info',
`log_status` int(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` datetime(6) NOT NULL COMMENT 'create datetime',
`log_modified` datetime(6) NOT NULL COMMENT 'modify datetime',
UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'AT transaction mode undo table' ROW_FORMAT = Compact;
2.2 order-service service
2.2.1 yaml To configure
server:
port: 8082
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: 64ed9ca7-d705-4655-b4e4-f824e420a12a
group: test
#sharding-jdbc Horizontal split table rule configuration
# Data source name , Multiple data sources are separated by commas
shardingsphere:
datasource:
names: m1
m1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3307/sharding-tx-order?useUnicode=true&useSSL=false&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password: lhzlx
# Horizontal sub table :tb_order_1/2/3, When splitting multiple tables , In turn, it's tables Tag post write logic
# tb_order_1/2/3 For the fact table in the database
# tb_order For writing SQL Logical table of operations in ,sharding-jdbc The fact table will be automatically operated according to the policy
# Configure node distribution
sharding:
tables:
tb_order:
actual-data-nodes: m1.tb_order_$->{
1..3}
# Appoint tb_order The primary key generation strategy of the table is SNOWFLAKE
key-generator.column: id
key-generator.type: SNOWFLAKE
# Appoint tb_order Table fragmentation strategy , The partitioning strategy includes partitioning key and partitioning algorithm , tb_order_1/2/3 All right 3 Remainder
table-strategy.inline.sharding-column: id
table-strategy.inline.algorithm-expression: tb_order_$->{
id % 3+1}
# open sql Output log
props:
sql:
show: true
seata:
enabled: true
application-id: ${
spring.application.name}
# The name of the transaction group , Corresponding service.vgroupMapping.default_tx_group=xxx Configured in default_tx_group
tx-service-group: default_tx_group
# Configure the correspondence between the transaction group and the cluster
service:
vgroup-mapping:
# default_tx_group Is the name of the transaction Group ,default Name the cluster
default_tx_group: default
disable-global-transaction: false
registry:
type: nacos
nacos:
application: seata-server
server-addr: 162.14.115.18:8848
group: SEATA_GROUP
namespace: 64ed9ca7-d705-4655-b4e4-f824e420a12a
username: nacos
password: nacos
cluster: default
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace: 64ed9ca7-d705-4655-b4e4-f824e420a12a
username: nacos
password: nacos
data-id: seataServer.properties
2.2.2 Service
Upstream services through @GlobalTransactional Annotations enable global transactions , Use storageClient Conduct feign call
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
@Resource
private StorageClient storageClient;
@Resource
private OrderMapper orderMapper;
/** * Create order * * @param order * @return */
@Override
@GlobalTransactional
public Long create(Order order) {
// Create order
long id = new Random().nextInt(999999999);
order.setId(id);
orderMapper.insert(order);
try {
// Record inventory information
storageClient.deduct(order.getId(), order.getCount());
// Simulate anomalies
// int a = 1 / 0;
} catch (FeignException e) {
log.error(" Order failure , reason :{}", e.contentUTF8(), e);
throw new RuntimeException(e.contentUTF8(), e);
}
return order.getId();
}
}
2.2.3 StorageClient
@FeignClient("storage-service")
public interface StorageClient {
/** * Deducting the inventory * * @param orderId * @param count */
@PostMapping("/storage")
void deduct(@RequestParam("orderId") Long orderId, @RequestParam("count") Integer count);
}
2.3 storage-service service
2.3.1 yaml To configure
server:
port: 8081
spring:
application:
name: storage-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: 64ed9ca7-d705-4655-b4e4-f824e420a12a
group: test
# stay dev Environment debug when , You can set the time to be longer
#heart-beat-interval: 1000 # Heartbeat interval . The unit is millisecond , Default 5*1000
heart-beat-timeout: 300000 # Cardiac arrest , No heartbeat , Will set the instance as unhealthy . The unit is millisecond , Default 15*1000
ip-delete-timeout: 4000000 #Ip Delete timeout , No heartbeat , The instance will be deleted . The unit is millisecond , Default 30*1000
#sharding-jdbc Horizontal split table rule configuration
# Data source name , Multiple data sources are separated by commas
shardingsphere:
datasource:
names: m1
m1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3307/sharding-tx-storage?useUnicode=true&useSSL=false&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password: lhzlx
# Horizontal sub table :tb_storage_1/2/3, When splitting multiple tables , In turn, it's tables Tag post write logic
# tb_storage_1/2/3 For the fact table in the database
# tb_storage For writing SQL Logical table of operations in ,sharding-jdbc The fact table will be automatically operated according to the policy
# Configure node distribution
sharding:
tables:
tb_storage:
actual-data-nodes: m1.tb_storage_$->{
1..3}
# Appoint tb_storage The primary key generation strategy of the table is SNOWFLAKE
key-generator.column: id
key-generator.type: SNOWFLAKE
# Appoint tb_storage Table fragmentation strategy , The partitioning strategy includes partitioning key and partitioning algorithm , tb_storage_1/2/3 All right 3 Remainder
table-strategy.inline.sharding-column: id
table-strategy.inline.algorithm-expression: tb_storage_$->{
id % 3+1}
# open sql Output log
props:
sql:
show: true
seata:
enabled: true
application-id: ${
spring.application.name}
# The name of the transaction group , Corresponding service.vgroupMapping.default_tx_group=xxx Configured in default_tx_group
tx-service-group: default_tx_group
# Configure the correspondence between the transaction group and the cluster
service:
vgroup-mapping:
# default_tx_group Is the name of the transaction Group ,default Name the cluster
default_tx_group: default
disable-global-transaction: false
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace: 64ed9ca7-d705-4655-b4e4-f824e420a12a
username: nacos
password: nacos
cluster: default
config:
type: nacos
nacos:
server-addr: 162.14.115.18:8848
group: SEATA_GROUP
namespace: 64ed9ca7-d705-4655-b4e4-f824e420a12a
username: nacos
password: nacos
data-id: seataServer.properties
2.3.2 StorageService
@Slf4j
@Service
public class StorageServiceImpl implements StorageService {
@Resource
private StorageMapper storageMapper;
/** * Deduct the amount of storage * * @param orderId * @param count */
@Override
public void deduct(Long orderId, int count) {
log.info(" Start recording inventory information ");
try {
long id = new Random().nextInt(999999999);
Storage storage = new Storage();
storage.setId(id);
storage.setOrderId(orderId);
storage.setCount(count);
storageMapper.insert(storage);
// Simulate anomalies
// int a = 1 / 0;
} catch (Exception e) {
throw new RuntimeException(" Inventory deduction failed , It may be that the inventory is insufficient !", e);
}
log.info(" Inventory information recorded successfully ");
}
}
3 test
There is no screenshot for demonstration during the test , It only shows the result , You can run code to set exceptions to verify
3.1 Downstream service is abnormal
stay order-service The service is normal , stay storage-service Service service Exception thrown in , Observe whether the data is successfully rolled back ; If tb_order And tb_storage There is no data , Indicates that the global transaction is successful ;
3.2 The upstream service is abnormal
order-service The service is executing storageClient.deduct() Method to throw an exception , stay storage-service The service is normal , Observe whether the data is successfully rolled back ; If tb_order And tb_storage There is no data , Indicates that the global transaction is successful ;
3.3 Final data consistency verification
We can complete the upstream service orderMapper.insert(order);`` Enter the breakpoint immediately after , The test will find that tb_order There's data in , The re release breakpoint makes the program execute abnormally , If you look at the database again, you will find tb_order The data in has been deleted ;
4、 Source code address
Seata value AT Pattern code implementation :《sharding-tx-seata》
边栏推荐
- Cann media data processing V2, jpegd interface introduction
- How to create a CSR (certificate signing request) file?
- Detailed explanation of select in golang (forward)
- 数据库MySQL语句期末复习 CTGU
- DMS的SQL结果集导出支持传参数吗?
- 今天开户今天能买股票吗?在线开户是安全么?
- 启牛学堂的vip证券账户是真的安全正规吗?怎么说
- Graphic system - 2 View drawing
- Small program graduation design based on wechat real estate intermediary house viewing appointment small program graduation design opening report function reference
- How to manage interface documents efficiently and gracefully
猜你喜欢

Analysis of response parsing process of SAP ui5 batch request

Industrial digitalization and new generation digitalization system design platform -- Lecture

EasyExcel 学习笔记

杂记:数据库go,begin,end,for,after,instead of

Small program graduation project based on wechat agricultural and sideline products agricultural products mall small program graduation project opening report function reference

记一次Emotet木马处理案例

kubeadm创建kubernetes集群

MCU modifies network hardware driver (PHY chip replacement)

图形系统——1. 布局加载

NFT流动性协议的安全困局—NFT借贷协议XCarnival被黑事件分析
随机推荐
第2章 处理文件、摄像头和图形用户界面cameo应用
软件测试的三个沟通技巧
Learning notes: how to time 10ms for 51 single chip microcomputer (STC89C52)
数据源只能连阿里云的云数据库吗?阿里云服务器里装的数据库连不上嘛?
Small program graduation project based on wechat subscription water supply mall small program graduation project opening report function reference
Applet graduation project is based on wechat property maintenance application property applet graduation project opening report function reference
Easyexcel learning notes
Small program graduation project based on wechat milk tea takeout mall small program graduation project opening report function reference
Small program graduation project based on wechat mobile mall small program graduation project opening report function reference
如何从RHEL 8升级到RHEL 9
9 excellent bitmap services
Database mysql statement final review CTGU
Go, begin, end, for, after, instead of
【云驻共创】昇腾异构计算架构CANN,助力释放硬件澎湃算力
图形系统——1. 布局加载
2022年7月计划(全力unreal)
NFT流动性协议的安全困局—NFT借贷协议XCarnival被黑事件分析
Small program graduation design based on wechat real estate intermediary house viewing appointment small program graduation design opening report function reference
Redis6 notes 04 master-slave replication, cluster, application problems, new redis6 features
Applet graduation design based on wechat beauty salon technician appointment applet graduation design opening report function reference