全部产品
云市场

基于 MySQL 5.6 的分布式事务

更新时间:2019-05-12 19:45:18

⚠️ 本文描述的分布式事务针对 MySQL 5.6 版本用户,或 DRDS 版本低于 5.3.4 的用户。

基本原理

分布式事务的原理请参考文档 DRDS 分布式事务基本原理

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

如何使用

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

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

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

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

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

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

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

常见问题

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

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

代码示例:

  1. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  2. import org.springframework.transaction.TransactionDefinition;
  3. import javax.sql.DataSource;
  4. import java.sql.Connection;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7. public class DrdsTransactionManager extends DataSourceTransactionManager {
  8. public DrdsTransactionManager(DataSource dataSource) {
  9. super(dataSource);
  10. }
  11. @Override
  12. protected void prepareTransactionalConnection(Connection con, TransactionDefinition definition) throws SQLException {
  13. try (Statement stmt = con.createStatement()) {
  14. stmt.executeUpdate("SET drds_transaction_policy = '2PC'"); // 以 2PC 为例
  15. }
  16. }
  17. }

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

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

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