JeeSite 快速开发平台
官方网站
    • 平台简介
    • 架构特点
    • 技术选型
    • 功能介绍
    • 安装部署
    • 常见问题
    • 目录结构
    • 更新日志
    • Vue 文档
    • BPM 文档
    • Cloud 文档
V5 演示
Vue 演示
💖联系
  • 我要提意见、文档纠错
  • JeeSite 代码库, 请⭐Star关注
  • JeeSite Vue 代码库, 请⭐关注
  • Spring Cloud 微服务架构
  • JeeSite 手机端/移动端
  • AI + RAG + CMS 人工智能
  • Flowable 中国式工作流
  • OAauth2 统一认证服务器
  • 政务内外网环境中间件
  • 访问 ThinkGem 官方博客
  • 点击进入,下拉查看动态
官方网站
    • 平台简介
    • 架构特点
    • 技术选型
    • 功能介绍
    • 安装部署
    • 常见问题
    • 目录结构
    • 更新日志
    • Vue 文档
    • BPM 文档
    • Cloud 文档
V5 演示
Vue 演示
💖联系
  • 我要提意见、文档纠错
  • JeeSite 代码库, 请⭐Star关注
  • JeeSite Vue 代码库, 请⭐关注
  • Spring Cloud 微服务架构
  • JeeSite 手机端/移动端
  • AI + RAG + CMS 人工智能
  • Flowable 中国式工作流
  • OAauth2 统一认证服务器
  • 政务内外网环境中间件
  • 访问 ThinkGem 官方博客
  • 点击进入,下拉查看动态
  • 快速了解

  • 后端开发手册

  • Vue前端手册

  • 经典前端手册

  • 扩展功能专题

  • 云服务技术架构

    • SaaS架构、多租户
    • 负载均衡、集群、高可用
    • SpringCloud 分布式 微服务
    • 分布式事务Seata、AT模式
      • Seata 是什么?
      • JeeSite 中如何使用?
        • 配置 Seata 服务端
        • 配置 Seata 客户端
    • 读写分离、分库分表方案
    • Spring Boot 监控系统
    • SkyWalking 追踪系统
    • ELK 日志收集分析
  • 技术支持与服务

微服务分布式事务解决方案 Seata 框架(AT模式)

# Seata 是什么?

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。在 Seata 开源之前,Seata 对应的内部版本在阿里经济体内部一直扮演着分布式一致性中间件的角色,帮助经济体平稳的度过历年的双11,对各BU业务进行了有力的支撑。经过多年沉淀与积累,商业化产品先后在阿里云、金融云进行售卖。2019.1 为了打造更加完善的技术生态和普惠技术成果,Seata 正式宣布对外开源,未来 Seata 将以社区共建的形式帮助其技术更加可靠与完备。

Seata 文档地址:http://seata.io/zh-cn/docs/overview/what-is-seata.html (opens new window)

# JeeSite 中如何使用?

适用于 JeeSite V4.2.3+ 版本。

# 配置 Seata 服务端

启动 Seata 服务

找到 /jeesite-cloud-module-seata/../SeataApplication.java 类,运行 Application 程序。

启动完成后,日志无报错,即可。

# 配置 Seata 客户端

下面依照 Seata 的 AT 模式实现客户端,举例如下:

1、执行数据库脚本

Seata 要求 AT 客户端需要建立一张日志表,执行脚本:

  • /jeesite-cloud-module-seata/db/client/at/mysql.sql
  • /jeesite-cloud-module-seata/db/client/at/oracle.sql
  • /jeesite-cloud-module-seata/db/client/at/postgresql.sql

2、关闭 JTA 开启 Seata 事务

打开分布式统一配置文件 /jeesite-cloud-config/../jeesite-cloud-yml/application.yml 如果使用 Nacos 请在 Nacos 里配置该文件。

# 关闭 JTA XA 事务
jdbc:
  jta:
    enabled: false

# 开启 Seata
seata:
  enabled: true
1
2
3
4
5
6
7
8

JeeSite 里的 JTA (XA) 事务是有 Atomikos 实现的,为了不对 LCN 事务所影响,所以需要关闭 JTA 事务。

2、关闭 Ribbon 的重试机制

打开分布式统一配置文件 /jeesite-cloud-config/../jeesite-cloud-yml/application.yml

# v4.3 之前版本需设置,之后 ribbon 已经移除,无需设置
ribbon:
  MaxAutoRetriesNextServer: 0
1
2
3

为什么要关闭服务调用的重试。远程业务调用失败有两种可能: (1),远程业务执行失败 (2)、远程业务执行成功,网络失败。对于第 2 种,事务场景下重试会发生,某个业务执行两次的问题。如果业务上控制某个事务接口的幂等,则不用关闭重试。

3、pom.xml 增加依赖

<!-- 分布式事务 -->
<dependency>
    <groupId>com.jeesite</groupId>
    <artifactId>jeesite-cloud-module-seata-client</artifactId>
    <version>${project.parent.version}</version>
</dependency>
1
2
3
4
5
6

添加到每个 Web 微服务的 pom.xml 文件中。

4、编写业务测试代码

由于 Seata 代码嵌入性非常低,不需要您关注太多事务方面的东西。开发模式和您本地开发模式一致。

在需要处理事务的 Controller 的方法上添加 @GlobalTransaction 注解即可,本地事务注解保留。

JeeSite Cloud 已为您编写好的测试代码,依次打开如下文件:

  • jeesite-cloud-module-core/../TransTestService.java
  • jeesite-cloud-module-test1/../TestDataService.java
  • jeesite-cloud-module-test2/../TestTreeService.java

全局搜索 @GlobalTransaction 并将每个文件里的 @GlobalTransaction 前的 // 注释去掉,并导入包即可(v4.3版本默认已经去掉注释)

为了方便理解,下面将关键测试代码进行展示,如下:

jeesite-cloud-module-core/../TransTestService.java

/**
 * 事务测试,第二个接口调用故意抛出异常
 */
@GlobalTransaction
@Transactional(readOnly=false)
public void transTest(TestData testData) {
	
	// 正常保存 testData 数据
	testData.setIsNewRecord(true);
	testData.setId(IdGen.randomBase62(5));
	testData.setTestInput(testData.getId());
	testData.setTestTextarea(testData.getId());
	testDataService.save(testData);
	
	// 保存 testTree 失败,抛出异常,testData 应回滚
	TestTree testTree = new TestTree();
	testTree.setIsNewRecord(true);
	testTree.setTreeCode(testData.getId());
	testTree.setTreeName(testData.getId());
	TestTree where = new TestTree();
	where.setParentCode(TestTree.ROOT_CODE);
	TestTree last = testTreeService.getLastByParentCode(where);
	if (last != null){
		testTree.setTreeSort(last.getTreeSort()+30);
	}
	// 设置一个超出数据库范围的值,抛出数据库异常
	StringBuilder sb = new StringBuilder();
	for (int i=0; i<500; i++){
		sb.append("transTest" + i);
	}
	testTree.setTreeName(sb.toString());
	testTreeService.save(testTree);

	// 有些情况可能需要手动回滚事务,调用该方法即可
	//try {
	//	GlobalTransactionContext.reload(RootContext.getXID()).rollback();
	//} catch (TransactionException e) {
	//	e.printStackTrace();
	//}
}

/**
 * 事务验证,返回空,则事务回滚成功
 */
public boolean transValid(TestData testData) {
	if (StringUtils.isBlank(testData.getId())){
		return true;
	}
	return testDataService.get(testData.getId()) == null;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

jeesite-cloud-module-core/../TransTestController.java

@Controller
@RequestMapping(value = "${adminPath}/trans")
public class TransTestController extends BaseController {

	@Autowired
	private TransTestService transTestService;
	
	/**
	 * 查询列表数据
	 */
	@RequestMapping(value = "test")
	@ResponseBody
	public String test(TestData testData) {
		try{
			transTestService.transTest(testData);
		}catch (Exception e) {
			logger.debug("事务测试信息,报错回滚:" + e.getMessage(), e);
		}
		boolean bl = transTestService.transValid(testData);
		return renderResult(Global.TRUE, "事务测试"+(bl?"成功,数据已":"失败,数据未")+"回滚!");
	}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

jeesite-cloud-module-test1/../TestDataService.java

@GlobalTransaction
@Transactional(readOnly=false)
public void save(TestData testData) {
		super.save(testData);
}
1
2
3
4
5

jeesite-cloud-module-test2/../TestTreeService.java

@GlobalTransaction
@Transactional(readOnly=false)
public void save(TestTree testTree) {
		super.save(testTree);
}
1
2
3
4
5

注意:Seata 的 @GlobalTransaction 注解,需要在 Controller 层上去加,否则可能不生效。

5、启动各个微服务

访问分布式事务,测试地址:http://127.0.0.1:8980/js/a/trans/test (opens new window)

若提示 “事务测试成功” 即正常运行。

进入 JeeSite 源码仓库页面,点击右上角 ⭐ Star 加星关注。

← SpringCloud 分布式 微服务 读写分离、分库分表方案→

联系我们:s.jeesite.com  |  微信号:jeesitex  |  邮箱:jeesite@163.com
© 2013-2025 济南卓源软件有限公司 版权所有 | Theme Vdoing

请关注 JeeSite 微信公众号,了解最新动态

  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式