本文描述的分布式事务针对MySQL 5.6版本用户,或PolarDB-X 1.0版本低于5.3.4的用户。

基本原理

对于MySQL 5.6版本,由于MySQL XA协议实现尚不成熟,PolarDB-X 1.0自主实现了2PC事务策略用于分布式事务。MySQL 5.7及更高版本中,推荐您使用XA事务策略。

如何使用

如果某个事务可能涉及多个数据分库,则需要将当前事务声明为分布式事务。如果事务仅涉及单个数据分库,则无需开启分布式事务,直接像MySQL单机事务那样即可,无需额外操作。

分布式事务开启方式如下:

在事务开启后,执行SET drds_transaction_policy = '...'即可。

MySQL命令行客户端使用示例(以2PC事务为例):

SET AUTOCOMMIT=0;
SET drds_transaction_policy = '2PC'; -- 建议MySQL 5.6用户使用
.... -- 业务SQL
COMMIT; -- 或ROLLBACK
            

Java JDBC代码示例(以2PC事务为例):

conn.setAutoCommit(false);
try (Statement stmt = conn.createStatement()) {
    stmt.execute("SET drds_transaction_policy = '2PC'");
}
// ... 运行业务SQL ...
conn.commit(); //或rollback()
            

常见问题

如何在Spring框架中使用分布式事务?

如果使用Spring的@Transactional注解开启事务,可以通过扩展事务管理器来开启PolarDB-X 1.0分布式事务。

代码示例:

import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class DrdsTransactionManager extends DataSourceTransactionManager {

    public DrdsTransactionManager(DataSource dataSource) {
        super(dataSource);
    }

    @Override
    protected void prepareTransactionalConnection(Connection con, TransactionDefinition definition) throws SQLException {
        try (Statement stmt = con.createStatement()) {
            stmt.executeUpdate("SET drds_transaction_policy = '2PC'"); // 以 2PC 为例
        }
    }
}
            

之后,在Spring配置中将上述类实例化,例如:

<bean id="drdsTransactionManager" class="my.app.DrdsTransactionManager">
     <property name="dataSource" ref="yourDataSource" />
</bean>
            

对于需要开启PolarDB-X 1.0分布式事务的类,加上注解@Transactional("drdsTransactionManager")即可。