1. 程式人生 > >Spring Cloud 中 分散式事務解決方案 -- 阿里GTS的使用

Spring Cloud 中 分散式事務解決方案 -- 阿里GTS的使用

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在啟用服務時,會有不穩定問題 ,一般待服務啟動一段時間就不會出現事務連結超時的異常。