安装

参考: Seata1.5.2安装配置(nacos)+部署

大致步骤

下载安装包

下载地址:http://seata.io/zh-cn/blog/download.html

直接解压到要安装的目录

在这里插入图片描述

修改application.yml文件

打开seata/conf/application.yml并作如下修改:

server:
  port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${user.home}/logs/seata
  extend:
    logstash-appender:
      destination: 127.0.0.1:4560
    kafka-appender:
      bootstrap-servers: 127.0.0.1:9092
      topic: logback_to_logstash

console:
  user:
    username: seata
    password: seata

seata:
  config:
    # support: nacos, consul, apollo, zk, etcd3
    type: nacos
    nacos:
      server-addr: 192.168.8.225:8848
      namespace: seata-namespace-id
      group: SEATA_GROUP
      username: nacos
      password: 密码
      data-id: seataServer.properties
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      application: seata-server
      server-addr: 192.168.8.225:8848
      group: SEATA_GROUP
      namespace: seata-namespace-id
      cluster: default
      username: nacos
      password: 密码
      
#  store:
    # support: file 、 db 、 redis
#    mode: file
#  server:
#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

以上只需修改seata的配置中心及注册中心即可,其他的配置保持默认,这里都是使用nacos来作配置中心和注册中心。
在这里插入图片描述

上一步配置中涉及到了nacos的namespace、group、data-id属性,所以需要在nacos中完成相应的配置

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

seataServer.properties的详细配置内容

store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://ip:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=数据库密码
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000

service.vgroupMapping.default_tx_group=default

由上一步可知:需要创建名为seata的数据库以及4张表global_table、branch_table、distributed_lock、lock_table

创建表的脚本seata已经提供了,在目录seata/script/server/db下,数据库创建好之后,直接执行脚本即可:
在这里插入图片描述
在这里插入图片描述

除了上一步创建的4张表之外,还需在自己的每一个业务数据库中创建一张表undo_log (只针对seata的AT模式)

undo_log的脚本如下:

-- ----------------------------
-- Table structure for undo_log
-- ----------------------------
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log`  (
  `branch_id` bigint(0) NOT NULL COMMENT 'branch transaction id',
  `xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'global transaction id',
  `context` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'undo_log context,such as serialization',
  `rollback_info` longblob NOT NULL COMMENT 'rollback info',
  `log_status` int(0) 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 = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'AT transaction mode undo table' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

在这里插入图片描述

启动及注意事项见下文

启动成功后,可进入seata后台ip+7091查看以及进入nacos中查看

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

其他:项目应用中的配置,在application.properties中新增如下配置

# ++++++ seata begin ++++++
seata.enabled=true
seata.tx-service-group=default_tx_group
seata.application-id=应用的id(针对seata)
seata.enable-auto-data-source-proxy=true
seata.data-source-proxy-mode=AT
seata.service.vgroup-mapping.default_tx_group=default

seata.registry.type=nacos
# dev env
seata.registry.nacos.server-addr=开发环境ip:8848
# test env
#seata.registry.nacos.server-addr=测试环境:8848
# release env
#seata.registry.nacos.server-addr=正式环境:8848
seata.registry.nacos.username=nacos
seata.registry.nacos.password=nacos密码
seata.registry.nacos.group=SEATA_GROUP
seata.registry.nacos.namespace=seata-namespace-id
seata.registry.nacos.application=seata-server

seata.config.type=nacos
# dev env
seata.config.nacos.server-addr=开发环境ip:8848
# test env
#seata.config.nacos.server-addr=测试环境:8848
# release env
#seata.config.nacos.server-addr=正式环境:8848
seata.config.nacos.username=nacos
seata.config.nacos.password=nacos密码
seata.config.nacos.group=SEATA_GROUP
seata.config.nacos.namespace=seata-namespace-id
seata.config.nacos.data-id=seataServer.properties
# ++++++ seata end ++++++

其他具体使用参考:https://blog.csdn.net/qq_29025955/article/details/134990525

注意事项

1. 启动时需要带上seata所在服务器的地址和端口(默认是8091)

windows:
在这里插入图片描述
linux:
在这里插入图片描述

2. seata的服务端配置文件application.yml中在配置nacos的namespace时,需要注意的是:对应的值是nacos中namespace的id, 而不是名称!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 客户端启动时,报错“io.seata.common.exception.FrameworkException: can not register RM,err:register error,role:RMROLE,err:cost 30948 ms”

解决: 重启Nacos , 重启seata服务器端。

4. seata分布事务中的事务标识 xid的传播,如果涉及到跨线程、异步调用时,必须手动实现xid的传播:

Seata 提供了 RootContext 类来管理全局事务上下文,通过 getXID() 方法可以获取当前事务的 XID。Seata 通过 ThreadLocal 来存储
事务上下文,这使得在同一个线程中,不同的方法和服务之间可以共享相同的事务上下文。

虽然 Seata 在大多数情况下能够自动传播事务上下文,但在某些特殊的场景下,比如使用异步调用、跨线程调用等,可能需要手动进
行事务上下文的传播。这是因为 ThreadLocal 的限制,当线程切换时,ThreadLocal 中的数据不会被自动传递

主要实现代码:

	            // 从Seata获取XID,并将其添加到Feign请求标头中
	            String xid = RootContext.getXID();
	            if (xid != null) {
	            // key固定为“TX_XID”,seata会自动去找“TX_XID”
	                requestTemplate.header("TX_XID", xid);
	            }

完整代码:

import javax.servlet.http.HttpServletRequest;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import io.micrometer.core.instrument.util.StringUtils;
import io.seata.core.context.RootContext;

@Configuration
public class ComonConfig {

	@Bean
	public RequestInterceptor requestInterceptor() {
		return new RequestInterceptor() {
			@Override
			public void apply(RequestTemplate requestTemplate) {
				ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
						.getRequestAttributes();
				HttpServletRequest request = attributes.getRequest(); // 老 request
				
	            // 从Seata获取XID,并将其添加到Feign请求标头中
	            String xid = RootContext.getXID();
	            if (xid != null) {
	                requestTemplate.header("TX_XID", xid);
	            }
				
				requestTemplate.header("Cookie", request.getHeader("Cookie")); // 新request
				String pageSizeDefault = "20";
				String pageNumDefalut = "1";
				String pageSize = request.getParameter("pageSize");
				String pageNum = request.getParameter("pageNum");
				if (StringUtils.isNotEmpty(pageSize)) {
					pageSizeDefault = pageSize;
				}
				if (StringUtils.isNotEmpty(pageNum)) {
					pageNumDefalut = pageNum;
				}
				requestTemplate.header("pageSize", pageSizeDefault);
				requestTemplate.header("pageNum", pageNumDefalut);
//				requestTemplate.header("Accept", "application/json;charset=UTF-8");
//				requestTemplate.header("Content-Type", "application/json;charset=UTF-8");
			}
		};
	}
}

5. 表undo_log可通过断点观察到产生的数据,请求完成后,数据会自动删除。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐