当前位置:网站首页>Detailed tutorial on distributed transaction Seata
Detailed tutorial on distributed transaction Seata
2022-07-31 11:07:00 【m0_54853503】
分布式事务Seata使用
seataLocalization of services and dockerSee this tutorial for deployment:分布式事务Seata安装:本地部署、docker部署seata
springboot项目配置
微服务环境:添加依赖
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>最新版</version>
</dependency>
<!--不使用注册中心、Configuration center does not add-->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.2.0及以上版本</version>
</dependency>
项目yml中添加seata配置
seata:
enabled: true
enable-auto-data-source-proxy: false
application-id: ${spring.application.name}
tx-service-group: my_tx_group
service:
vgroup-mapping:
my_tx_group: default
# Do not use the registration center and configuration center without adding the following configuration
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: "SEATA_GROUP"
namespace: "seata"
dataId: "seataServer.properties"
username: ""
password: ""
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: "SEATA_GROUP"
namespace: "seata"
username: ""
password: ""
数据库中添加回滚日志表.
Data source connections are added for each database undo_log 表
CREATE TABLE
sys_seata_undo_log
(id
bigint(20) NOT NULL AUTO_INCREMENT,branch_id
bigint(20) NOT NULL,xid
varchar(100) NOT NULL,context
varchar(128) NOT NULL,rollback_info
longblob NOT NULL,log_status
int(11) NOT NULL,log_created
datetime NOT NULL,log_modified
datetime NOT NULL,
PRIMARY KEY (id
),
UNIQUE KEYux_undo_log
(xid
,branch_id
)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
注意:
1、nacos注册中心配置group项,Server和ClientThe value of the terminal must be the same.
2、Required to use multiple data sources:
关闭seata的数据源代理 seata.enable-auto-data-source-proxy=false,Use multiple data source agents
Enable multiple data source pairsseata的支持spring.datasource.dynamic.seata=true
3、默认的ATThe schema requires a rollback journal table to be added to the database"sys_seata_undo_log"
4、已支持从一个Nacos dataId中获取所有配置信息,你只需要额外添加一个dataId配置项.此处dataId为seataServer.properties.
注:当client配置了seata.config,clientend will take prioritynacos读取"seataServer.properties"中的配置参数,在yml配置的service、clientand other parameters no longer take effect.
故若在yml中修改seata server相关参数,请注释掉seata.config ,再添加配置.
nacos详细参数配置:https://seata.io/zh-cn/docs/user/configurations.html
- 5、seataServer.properties 中service.vgroupMapping.default_tx_group=default
This configuration is the transaction group name.其中“default_tx_group”与“default”都可以自定义,However, this configuration item on the client and server must be consistent,否则会报错.
The client configuration is shown below,其中 seata.tx-service-group的值,要与default_tx_group一致;seata.service.vgroup-mapping.default_tx_group的值,要与default一致.
seata:
tx-service-group: default_tx_group
service:
vgroup-mapping:
default_tx_group: default
AT模式使用
When a global transaction needs to be initiatedservice方法上添加注解 @GlobalTransactional,
使用Fiegn、restTemplateetc. to send the request,Providers only [email protected]保证本地事务
SeataThree identities are involved in a global transaction
TC 事务协调者,对应seata服务
TM事务管理者,对应baseThe method in the service to initiate a global transaction
RM资源管理者,Corresponds to the workflow service
注意问题:
- seata通过线程变量 XID 判断TC与RMunder the same transaction,It is now supported to userestTemplate与FeignThe way to send the request is automatically carriedxidto the callee,
Other methods can be usedxid放入请求头中,key为"TX_XID",RMIt will be automatically obtained in the request header.If you use other methods, you need to guarantee it yourselfxid的传递.
- The callee raises an exception without rolling back:
when the calleeRM产生异常时,for the callerTMThe abnormal status code can be received correctly,使FeignAn exception can be thrown to initiate a global transaction rollback,RMIt is best not to add exception handling to intercept exceptions.
若RM异常被拦截,需要TM通过FeignThe returned custom status code determines whether the callee generates an exception,and throw the exception manually.如下:
ApiResponse apiResponse = feignClientService.clientB();
if(apiResponse.getCode()!= 10000){
throw new RuntimeException(apiResponse.getMsg());
}
- ATSchemas are implemented based on database local transactions,The parties involved in a distributed transaction,All need to add a rollback log table in each(undo_log).
可修改nacos中seataServer.properties文件client.undo.logTable=表名 Customize the name of the rollback log table.
使用Demo
服务A调用服务B,作为调用方A添加@GlobalTransaction注解
@Service
public class AService {
@GlobalTransactional
public ApiResponse insertSomething() {
log.info("===================================");
log.info("AService XID: "+ RootContext.getXID());
aMapper.insertSomething(); // A对数据库进行插入操作
ApiResponse apiResponse = feignClientService.clientB(); // 通过Feign 调用服务B
// If the callee's exception status code is intercepted, Judging the custom status code to manually throw an exception
if(apiResponse.getCode()!= 10000){
throw new RuntimeException(apiResponse.getMsg());
}
// error(); // Let go of this annotation,抛出异常
return ApiResponse.success();
}
}
BService as the callee,添加@Transactional保证本地事务
@Service
public class BService {
@Transactional
public ApiResponse insertSomething() {
log.info("==========================================");
log.info("XID: "+ RootContext.getXID());
bMapper.insertSomething();
// error(); // Let go of this annotation,抛出异常.
return ApiResponse.success();
}
}
TCC模式使用
实际上,Seata的AT模式基本上能满足我们使用分布式事务80%的需求,But it involves databases and middleware that do not support transactions(如redis)等的操作,或ATA database whose schema is not yet supported(目前AT支持Mysql、Oracle与PostgreSQL)、跨公司服务的调用、Cross-language application calls may require manual control of the entire two-phase commit process,则需要结合TCC模式.不仅如此,TCCmode is also supported with AT模式混合使用.
一、TCC模式的概念
一个分布式的全局事务,整体是两阶段提交Try-[Comfirm/Cancel] 的模型.在Seata中,AT模式与TCCPatterns are, in fact, concrete implementations of two-phase commit.他们的区别在于:
AT 模式基于支持本地 ACID 事务 的 关系型数据库(目前支持Mysql、Oracle与PostgreSQL):
一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录. 二阶段 commit 行为:马上成功结束,自动异步批量清理回滚日志. 二阶段 rollback 行为:通过回滚日志,自动生成补偿操作,完成数据回滚.
相应的,TCC 模式,不依赖于底层数据资源的事务支持:
一阶段 prepare 行为:调用 自定义 的 prepare 逻辑. 二阶段 commit 行为:调用 自定义的 commit 逻辑. 二阶段 rollback 行为:调用 自定义的 rollback 逻辑.
所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中.
简单点概括,SEATA的TCCPatterns are manualAT模式,它允许你自定义两阶段的处理逻辑而不依赖AT模式的undo_log.
二、前提准备
- 注册中心 nacos
- seata服务端(TC)
This chapter focuses onTCC模式的实现,See the previous document for the construction of the project
三、TM与TCC-RM搭建
3.1 定义TCC接口
由于我们使用的是 SpringCloud + Feign,Feign的调用基于http,So here we [email protected]便可.值得注意的是,@LocalTCC一定需要注解在接口上,此接口可以是寻常的业务接口,只要实现了TCC的两阶段提交对应方法便可,TCC相关注解如下:
@LocalTCC适用于SpringCloud+Feign模式下的TCC
@TwoPhaseBusinessAction注解prepare方法,其中name为当前tcc方法的bean名称,写方法名便可(全局唯一),commitMethod指向提交方法,rollbackMethod指向事务回滚方法.指定好三个方法之后,seata会根据全局事务的成功或失败,去帮我们自动调用提交方法或者回滚方法.
@BusinessActionContextParameter注解可以将参数传递到二阶段(commitMethod/rollbackMethod)的方法.
BusinessActionContext便是指TCC事务上下文
@LocalTCC
public interface TccService{
/**
* 定义两阶段提交
* name = 该tcc的bean名称,全局唯一
* commitMethod = commit 为二阶段确认方法
* rollbackMethod = rollback 为二阶段取消方法
* BusinessActionContextParameter注解 传递参数到二阶段中
* @param params -入参
* @return String
*/
@TwoPhaseBusinessAction(name = “prepare”, commitMethod = “commit”, rollbackMethod = “rollback”)
String prepare(
@BusinessActionContextParameter(paramName = “params”) Map<String, String> params
);/** * 确认方法、可以另命名,但要保证与commitMethod一致 * context可以传递try方法的参数 * @param context 上下文 * @return boolean */ @Override boolean commit(BusinessActionContext context); /** * 二阶段取消方法 * @param context 上下文 * @return boolean */ @Override boolean rollback(BusinessActionContext context);
}
3.2 TCC接口的业务实现
在方法prepare中使用@TransationalOperations in relational databases can be rolled back directly through local transactions,而非关系型数据库等中间件的回滚操作可以交给rollbackMethod方法处理.
使用context.getActionContext(“params”)便可以得到一阶段try中定义的参数,在二阶段对此参数进行业务回滚操作.
注意1:此处亦不可以捕获异常(同理切面处理异常),否则TCC将识别该操作为成功,二阶段直接执行commitMethod.
注意2:TCCThe mode requires developers to ensure idempotency and transaction anti-suspension
注意3: commit()与rollback()方法返回值必须为true,当返回值不为trueOr throw an exception in the method,seata会不断回调commit或rollback方法,直到返回值为true.
public class TccServiceImpl implements TccService {
private static Logger log = LoggerFactory.getLogger(TccServiceImpl.class);
@Autowired
TccDAO tccDAO;
@Override
@Transational
public String prepare(Map<String, String> params) {
log.info("xid = " + RootContext.getXID());
//todo 实际的操作,或操作MQ、redis等
tccDAO.insert(params);
//放开以下注解抛出异常
//throw new RuntimeException("服务tcc测试回滚");
return "success";
}
@Override
public boolean commit(BusinessActionContext context) {
log.info("xid = " + context.getXid() + "提交成功");
//todo 若一阶段资源预留,这里则要提交资源
return true;
}
@Override
public boolean rollback(BusinessActionContext context) {
//todo 这里写中间件、非关系型数据库的回滚操作
System.out.println("please manually rollback this data:" + context.getActionContext("params"));
return true;
}
}
@RestController
@RequestMapping("/at")
public class AtController {
@Autowired
AtService atService;
@PostMapping("/at-insert")
public String insert(@RequestBody Map<String, String> params) {
return atService.insert(params);
}
}
@Override
@DSTransactional
public String insert(Map<String, String> params) {
log.info("------------------> xid = " + RootContext.getXID());
// 调用master分支
atDAO.insert(params);
atDAO.insert(params);
atDAO.insert(params);
atDAO.insert(params);
// 调用slave分支
params.put("name", "B服务测试");
studentMapper.insert(params);
studentMapper.insert(params);
studentMapper.insert(params);
studentMapper.insert(params);
return "success";
}
@Mapper
@DS("master")
public interface AtDAO {
@Insert("insert into service_at (name) value (#{name})")
int insert(Map<String, String> map);
}
@Mapper
@DS("slave")
public interface StudentMapper {
@Insert("insert into student (name) value (#{name})")
int insert(Map<String, String> map);
}
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在.深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小.自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前.因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担.添加下方名片,即可获取全套学习资料哦
边栏推荐
猜你喜欢
透过开发抽奖小程序,体会创新与迭代
线程池 ThreadPoolExecutor 详解
“带薪划水”偷刷阿里老哥的面经宝典,三次挑战字节,终成正果
3D激光SLAM:LeGO-LOAM论文解读---点云分割部分
5 个开源的 Rust Web 开发框架,你选择哪个?
若枚举映射的值不存在,则不进行反序列化
Sql optimization summary!detailed!(Required for the latest interview in 2021)
使用内存映射加快PyTorch数据集的读取
内网渗透学习(四)域横向移动——SMB和WMI服务利用
一文带你了解redux的工作流程——actionreducerstore
随机推荐
SQL如何从字符串截取指定字符(LEFT、MID、RIGHT三大函数)
Make your own dataset in FCN and train it
一文吃透接口调用神器RestTemplate
《云原生的本手、妙手和俗手》——2022全国新高考I卷作文
darknet 训练分类网络
How SQL intercepts specified characters from strings (three functions of LEFT, MID, RIGHT)
线程池 ThreadPoolExecutor 详解
文件包含漏洞
A Method for Ensuring Data Consistency of Multi-Party Subsystems
Distributed Transactions - Introduction to Distributed Transactions, Distributed Transaction Framework Seata (AT Mode, Tcc Mode, Tcc Vs AT), Distributed Transactions - MQ
mpu9150(driverack pa简明教程)
C#之泛型、委托、事件及其使用
《JUC并发编程 - 高级篇》06 - 共享模型之不可变(不可变类的设计 | 不可变类的使用 | 享元模式)
In half a month, MySQL has been consolidated again, and a tens of thousands of words "super hard core" article has been sorted out!
一文带你了解redux的工作流程——actionreducerstore
What does "chmod 777-R filename" mean?
学自动化测试哪个培训机构好 试听课程后就选了这个地方学习
逆置问题--重点
PyQt5快速开发与实战 9.5 PyQtGraph在PyQt中的应用 && 9.6 Plotly在PyQt中的应用
矩形脉冲波形的占空比及脉冲和瞬态特征的测量