本文介绍如何使用柔性事务。

开启柔性事务

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

mysql> SET drds_transaction_policy = 'flexible';

mysql> SHOW VARIABLES LIKE 'drds_transaction_policy'; 
+-------------------------+----------+
| VARIABLE_NAME           | VALUE    |
+-------------------------+----------+
| drds_transaction_policy | FLEXIBLE |
+-------------------------+----------+
1 row in set (0.07 sec)

Java代码示例:

conn.setAutoCommit(false);

try (Statement stmt = conn.createStatement()) {
    stmt.execute("set drds_transaction_policy = 'flexible'");
}

// ... 运行业务 SQL ...
conn.commit(); // 或 rollback()
注意
  • 只允许在SET autocommit = 0的前提下设置drds_transaction_policy属性,否则报错。
  • 当前会话中设置的drds_transaction_policy属性会在SET autocommit = 1后自动重置。

SQL后置执行

后置执行是PolarDB-X 1.0柔性事务提供的一项功能,帮助您进一步提高事务性能。

声明为后置执行的SQL将在事务成功后被执行,从而保证最终一致性。将不影响事务结果的SQL声明为后置执行,能进一步减少事务锁的粒度,提高吞吐量。

使用 Hint /*TDDL:DEFER*/ 可将SQL标记为后置执行,例如:

/*TDDL:DEFER*/ UPDATE accounts SET balance = balance + 100 WHERE id = 'B';

也可以和其他Hint混合使用,例如:

/*TDDL:NODE=1 AND DEFER*/ UPDATE accounts SET balance = balance + 100 WHERE id = 'B';

PolarDB-X 1.0保证后置执行的SQL一定且仅成功执行一次。

说明 5.3.1版本暂不支持后置执行。

增量回滚

PolarDB-X 1.0柔性事务对于“增量操作”的回滚有专门优化。

当事务中的UPDATE语句包含增量操作,例如:balance = balance - 100,则会在回滚语句中使用balance = balance + 100进行补偿。由于增量操作的结果与顺序无关,这样即使事务异步回滚,也不会覆盖其他业务的更新结果。

增量操作的定义是UPDATE语句符合以下格式:

UPDATE {表名} SET {列名} = {列名} [+/-] {常量表达式}, ... WHERE {条件表达式}

示例:

UPDATE account SET balance = balance - 100 WHERE id = 'B' AND balance >= 100

PolarDB-X 1.0自动生成的回滚语句为:

UPDATE account SET balance = balance + 100 WHERE id = 'B'

增量回滚对账户、积分、库存这样的字段非常有用,而这些字段又经常是需要用分布式事务严格保证一致性的关键数据。建议在应用中尽量对这一类字段采用“增量操作”的方式更新,既节省了一次数据库操作(SELECT),又避免了柔性事务“回滚覆盖”的风险。