seata的安装及基本使用
- 安装
- 注意事项
- 1. 启动时需要带上seata所在服务器的地址和端口(默认是8091)
- 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”
- 4. seata分布事务中的事务标识 xid的传播,如果涉及到跨线程、异步调用时,必须手动实现xid的传播:
- 5. 表undo_log可通过断点观察到产生的数据,请求完成后,数据会自动删除。
安装
Seata1.5.2安装配置(nacos)+部署
注意事项
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) {
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");
}
};
}
}