springcloud Alibaba 踩坑记 seata 分布式事务问题分析

3,540 阅读3分钟

本文采用是springcloud alibaba的组件集成,适合刚入坑seata的小白 以一篇基础文章作为开始:使用 Seata 实现分布式事务 源码和配置文章已经说得很清楚了,这篇文章主要写seata一些容易被忽略的坑点 下载:seata-server

坑点一

如果你的项目采用是spring-cloud-alibaba-seata 0.9.0版本或以下的话,它集成了fescar-spring的0.4.2版本,如果你的seata-server服务端是采用0.5.0以上建议还是降低版本,采用0.4.2版本。因为0.4.2版本解压是fescar-server名字,意不意外。这就是坑。而且项目引入seata依赖会与旧版本的fescar依赖冲突。

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-alibaba-seata</artifactId>
                <version>0.9.0.RELEASE</version>
            </dependency>

\[外链图片转存失败(img-yNAbSfpl-1563245429073)(evernotecid://2FBF5D65-056C-45EC-B24E-E30918E6500F/appyinxiangcom/17498440/ENResource/p466)\]

如果你的项目采用是spring-cloud-alibaba-seata 0.9.1(这个的seata为0.5.2)版本以上的话,那恭喜你。你可以使用seata-server的0.5.2以上的版本了。只需要在依赖这样引入

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <version>0.9.1.BUILD-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>seata-server对应的版本</version>
        </dependency>

\[外链图片转存失败(img-TclWZjbj-1563245429074)(evernotecid://2FBF5D65-056C-45EC-B24E-E30918E6500F/appyinxiangcom/17498440/ENResource/p465)\]

坑点二

  • 需要在每个服务中的resources文件中添加两个文件file.conf和registry.conf

\[外链图片转存失败(img-PUDV5nKk-1563245429075)(evernotecid://2FBF5D65-056C-45EC-B24E-E30918E6500F/appyinxiangcom/17498440/ENResource/p467)\]

  • 具体以seata-server中的file.conf和registry.conf为准。
    \[外链图片转存失败(img-MIIeToRR-1563245429075)(evernotecid://2FBF5D65-056C-45EC-B24E-E30918E6500F/appyinxiangcom/17498440/ENResource/p468)\]

坑点三

如果你的项目采用是spring-cloud-alibaba-seata 0.9.0版本或以下的话,因为它集成了fescar-spring的0.4.2版本,如果你是使用nacos来配置参数的话,建议使用seata-server 0.4.2,不然引入seata0.5.0以上的版本依赖会混淆,容易报以下错误

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'globalTransactionScanner' defined in class path resource [org/springframework/cloud/alibaba/seata/GlobalTransactionAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError
Caused by: java.lang.ExceptionInInitializerError: null
Caused by: java.lang.NullPointerException: Name is null
	at java.lang.Enum.valueOf(Enum.java:236) ~[na:1.8.0_201]
	at com.alibaba.fescar.core.rpc.netty.TransportProtocolType.valueOf(TransportProtocolType.java:25) ~[fescar-core-0.4.2.jar:na]
	at com.alibaba.fescar.core.rpc.netty.NettyBaseConfig.<clinit>(NettyBaseConfig.java:114) ~[fescar-core-0.4.2.jar:na]
	... 23 common frames omitted

\[外链图片转存失败(img-dtZqVLHR-1563245429076)(evernotecid://2FBF5D65-056C-45EC-B24E-E30918E6500F/appyinxiangcom/17498440/ENResource/p469)\]

坑点四

数据源需要引入druid依赖

/**
 * @author lgt
 */
@Configuration
public class DatabaseConfiguration {

	@Bean
	@ConfigurationProperties(prefix = "spring.datasource")
	public DruidDataSource druidDataSource() {
		return new DruidDataSource();
	}

	/**
	 * 需要将 DataSourceProxy 设置为主数据源,否则事务无法回滚
	 *
	 * @param druidDataSource The DruidDataSource
	 * @return The default datasource
	 */
	@Primary
	@Bean("dataSource")
	public DataSource dataSource(DruidDataSource druidDataSource) {
		return new DataSourceProxy(druidDataSource);
	}

}

ps:上面是 seata 数据源的配置,数据源采用 druid 的DruidDataSource,但实际 jdbcTemplate 执行时并不是用该数据源,而用的是 seata 对DruidDataSource的代理DataSourceProxy,所以,与 RM 相关的代码逻辑基本上都是从DataSourceProxy这个代理数据源开始的。

坑点五

  • 0.6.1及之前版本的启动命令是:sh seata-server.sh 8091 file 127.0.0.1
  • 0.7.0 及之后版本的启动命令是:sh seata-server.sh -p 8091 -h 127.0.0.1 -m file
  • 0.5.2及之前的版本的数据库和之后版本数据库是不一样,详细以github的文件一致

最后给大家一句提醒,seata虽然是蚂蚁金服推出的,但是也有许多版本不一致的,大家要注意版本问题,本文会持续更。。。