本文介绍如何使用柔性事务。
开启柔性事务
在事务开启后,执行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),又避免了柔性事务“回滚覆盖”的风险。