Spring Cloud 中 分布式事务解决方案 -- 阿里GTS的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Paranoia_ZK/article/details/79567722

1:依赖引入

        <!--gts相关-->
        <!--数据库连接-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--阿里druid数据库链接依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>com.taobao.txc</groupId>
            <artifactId>txc-client</artifactId>
            <version>${txc.version}</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/../../../../lib/txc-client-2.0.69.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>com.alibaba.dauth</groupId>
            <artifactId>sdk-client</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!-- OTHERS -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>com.taobao.middleware</groupId>
            <artifactId>logger.api</artifactId>
            <version>0.1.5</version>
        </dependency>
        <dependency>
            <groupId>com.taobao.diamond</groupId>
            <artifactId>diamond-client</artifactId>
            <version>edas-3.7.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.1.7</version>
        </dependency>

2:配置相关

    <bean id="dataSource" class="com.taobao.txc.datasource.cobar.TxcDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password">
            <value><![CDATA[${jdbc.password}]]></value>
        </property>
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
    </bean>

    <!-- 定义声明式事务,要想让事务annotation感知的话,要在这里定义一下,spring才能感知到 -->
    <!--<property name="accessKey" value="xxx"/>-->
    <!--<property name="secretKey" value="xxx"/>-->
    <bean class="com.taobao.txc.client.aop.TxcTransactionScaner">
        <constructor-arg value="myapp"/><!-- 应用名,用户自定义 -->
        <constructor-arg value="dXXXXXXXXXXX"/><!-- 事务分组名 -->
        <constructor-arg value="1"/>
        <constructor-arg value="https://test-cs-gts.aliyuncs.com"/>
    </bean> 

3:注意事项

  • 启动类将第二步的配置文件引入 
    @ImportResource({"classpath:META-INF/applicationContext.xml"})
  • 微服务中所有的模块都需要做第一步和第二步的操作,并注意scaner设置的应用名应唯一
  • 第二步的配置文件中的scaner只适用于本地化开发,线上修改如下
        <bean class="com.taobao.txc.client.aop.TxcTransactionScaner">
            <constructor-arg value="myapp"/><!-- 应用名,用户自定义 -->
            <constructor-arg value="xxxxxxxx"/><!-- 事务分组名 -->
            <constructor-arg value="1"/>
            <property name="accessKey" value="xxx"/>
            <property name="secretKey" value="xxx"/>
        </bean>

  • 事务发起方业务处理类添加注解 
    @TxcTransaction(timeout = 1000 * 6) timeout默认为6000,为事务超时时间。
    @TxcTransaction(timeout = 1000 * 6)
    public Map<String, String> getMoney(String id) {
        String xid = TxcContext.getCurrentXid();
        TxcContext.bind(xid,null);
        logger.info("查询service : " + xid);
        Map<String, String> map = new HashMap<>();
        map.put("one", feignHelloService.getOne(id, xid));
        map.put("two", feignHelloService2.getOne(id, xid));
        TxcContext.unbind();
        return map;
    }

注意代码中我们获取了TXC中的事务ID - > xid  ,这个xid需要延服务链路传递到服务下游,这样下游的事务就按照最外层事务发起方的事务走。注意bind & unbind 两个方法,是为我们的事务和阿里GTS-SERVER的绑定操作,业务下游得到xid之后同样需要进行同样的绑定操作。若项目采用阿里EDAS分布式服务框架,xid的绑定操作无须编码,edas会自己传递。

  • 本地启用GTS事务分组需阿里技术人员将分组分配到公网,因为GTS默认只支持经典网络类型的ECS。或直接采用阿里内部公网事务分组 txc_test_public.1129361738553704.QD  免费版GTS在启用服务时,会有不稳定问题 ,一般待服务启动一段时间就不会出现事务链接超时的异常。

jar包下载地址


阅读更多

扫码向博主提问

Paranoia_ZK

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • 微服务
  • 多线程
  • 后端
去开通我的Chat快问
换一批

没有更多推荐了,返回首页