AT 模式接入适用的场景包括跨数据库事务、MQ 的消息事务、EDAS 的服务事务及多场景混合型事务方案。本文介绍如何基于 @TxcTransaction 注解使用 GTS 服务。

前提条件

在使用 AT 模式接入 GTS 前,请先完成以下工作:

条件和约束

AT 模式的原理要求全局事务涉及的数据库系统SchemaSQL 语句必须符合一定的规范。

  • 数据库系统
    • 支持事务,目前支持 MySQL(RDS、PolarDB、原生MySQL)、PostgreSQL(RDS、自建)、Oracle等数据库。
    • 数据库表名大小写不敏感。
    • 修改方法,例如,在 MySQL 配置文件 my.cnf 中的 [mysqld] 后添加 lower_case_table_names=1,然后重启 MySQL 服务。
  • Schema
    • 不支持使用数据库和 SQL 的关键字做表名。
    • 必须定义主键,且必须是唯一主键,不支持复合主键。
  • SQL 语句

    只针对 DML 语句(INSERT、UPDATE、DELETE),查询语句(SELECT),与 GTS 工作机制无关,没有限制。

    • 不支持修改主键的语句。
    • 语句涉及主键的值,只支持确定值或列自增,不支持函数。例如:
      INSERT INTO table_name (PK, ...) VALUES (uuid() ...)
    • 不支持嵌套语句。例如:
      INSERT INTO table_name SELECT ...
      WHERE column_name IN SELECT ...

配置应用代码

通过审批的事务分组可以用于客户的应用代码中,需引入 GTS SDK 开发包,并添加依赖。

  1. 在 Spring 的配置文件中将申请好的事务分组名配置到 com.taobao.txc.client.aop.TxcTransactionScaner bean 中,并将阿里云账号中的Access Key ID和Access Key Secret配置到 accessKeysecretKey 两个属性上。
    <bean class="com.taobao.txc.client.aop.TxcTransactionScaner">
        <constructor-arg value="test111.1325460969176422.BJ"/>
        <property name="accessKey" value="xxxx"/>
        <property name="secretKey" value="xxxx"/>
    </bean>            
  2. 在需要启动全局事务的方法前添加 @TxcTransaction(appName=“myapp”) 注解。
    其中 appName 的值为事务别名,可以在 GTS 控制台上查询。
    @TxcTransaction(appName = "myapp")
    public void hello() {
        ...
    }           
  3. 在 Spring 配置文件中声明用到的含有 @TxcTransaction 注解的应用类,并使用这个 bean 的实例调用注解方法。
     <bean id="bussiness" class="com.taobao.txc.tests.Bussiness" init-method="init">
     </bean>            
    Bussiness bussiness = (Bussiness) context.getBean("bussiness");
    //用实例化的bean调用GTS注解方法hello,使hello方法内的操作加入一个GTS事务
    bussiness.hello();           
  4. 如果使用的数据源是 MySQL、DRDS(5.3及以上版本,低于 5.3 版本请参见注意事项。)、Oracle、RDS、PostgreSQL ,需要配置为 GTS 的数据源。
        <bean id="DataSource_rds" class="com.taobao.txc.datasource.cobar.TxcDataSource">
            <property name="url" value="jdbc:mysql://xxxxx" />
            <property name="username" value="xxx" />
            <property name="password" value="xxx" />
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        </bean>           
  5. 在加入 GTS 事务的所有数据库中建表 txc_undo_log
    CREATE TABLE `txc_undo_log` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
      `gmt_create` datetime NOT NULL COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL COMMENT '修改时间',
      `xid` varchar(100) NOT NULL COMMENT '全局事务 ID',
      `branch_id` bigint(20) NOT NULL COMMENT '分支事务 ID',
      `rollback_info` longblob NOT NULL COMMENT 'LOG',
      `status` int(11) NOT NULL COMMENT '状态',
      `server` varchar(32) NOT NULL COMMENT '分支所在 DB IP',
      PRIMARY KEY (`id`),
      KEY `unionkey` (`xid`,`branch_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=211225994 DEFAULT CHARSET=utf8 COMMENT='事务日志表';            

    通过上述配置可以将多个数据源加入一个事务中,多个数据源中的数据会保持强一致。一旦有异常返回给包含 @TxcTransaction 注解的方法,都会导致这个全局事务数据回滚到之前的状态。

添加应用依赖

GTS 应用代码的依赖包含两部分:

  • Spring: GTS 依赖 Spring 实现了 @TxcTransaction 注解的事务感知能力,因此,GTS 对 Spring 框架是强依赖的。
  • 基础依赖包和数据库驱动包。
  1. 在 GTS 工程的 pom.xml 文件中添加 Spring 依赖。
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring-version}</version>
    </dependency>                    
    说明 Spring 3.0 及以上版本对 Spring Bean 提供了稳定的性能和功能支持,且在实际使用中较为普遍,建议使用。使用 Spring 3.0 以上版本依赖,请在上面的实例代码前添加版本字段。
    <properties>
         <spring-version>3.2.17.RELEASE</spring-version>
    </properties>                    
  2. pom.xml 文件中,配置基础依赖包和数据库驱动包的依赖。
    • 日志打印:GTS 客户端依赖 SLF4J 接口编程,客户端 txcXXXX.log 的打印依赖应用在配置文件中指定的日志实现,logback 可以更快更好的实现日志打印。
    • 版本:在将 MQ、EDAS 等加入事务时,使用最新版本可以更好的和 GTS 兼容。
    • 数据源:下面实例中的数据源为 MySQL,当需要使用其它资源时,请修改 MySQL 依赖部分字段。
    <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.13</version>
    </dependency>
    <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
    </dependency>
    <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
    </dependency>
    <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.1</version>
    </dependency>
    <dependency>
            <groupId>com.taobao.middleware</groupId>
            <artifactId>logger.api</artifactId>
            <version>0.2.0</version>
    </dependency>
    <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
    </dependency>
    <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.0.33.Final</version>
    </dependency>
    <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.81</version>
    </dependency>
    <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>druid</artifactId>
             <version>1.0.17</version>
    </dependency>
    <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
    </dependency>       
    <dependency>
            <groupId>com.taobao.diamond</groupId>
            <artifactId>diamond-client</artifactId>
            <version>edas-3.7.3</version>
    </dependency>
    <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
    </dependency>
                            

执行结果

配置完成后,在 GTS 控制台可以查看这些事务及其分组的状态。事务总览