一、功能简介
| Hint 名称 | 作用范围 | 用途 |
| TXSQL_FORCE_LOCK | 事务级 | 在一个事务里更新多个不同热点行 |
| TXSQL_FORCE_LOCK_INDEPENDENT_GROUP | 单热点行级 | 允许同一事务对同一热点行进行多次访问 |
二、语法格式
Hint 使用 MySQL 标准的 /*+ … */ 语法,紧跟在 UPDATE / INSERT / DELETE 关键字之后:
UPDATE /*+ TXSQL_FORCE_LOCK */ table_name SET col = … WHERE …;UPDATE /*+ TXSQL_FORCE_LOCK TXSQL_FORCE_LOCK_INDEPENDENT_GROUP */ table_name SET col = … WHERE …;
三、关键放置规则(请务必遵守)
·TXSQL_FORCE_LOCK 必须放在事务的第一条 DML 语句上。
·放对位置:整个事务进入 FORCE_LOCK 模式,后续 DML 不需要再带 Hint。
·放在非首条 DML:Hint 被忽略并打 warning,事务仍按老的约束执行。
·TXSQL_FORCE_LOCK_INDEPENDENT_GROUP 必须放在事务首次访问目标热点行的那条 DML 上。
·该 Hint 只有在事务已经是 TXSQL_FORCE_LOCK 时才生效,否则会在解析期被丢弃并打 warning。
·目标热点行的属性在首次访问时即一次性确定;后续再次访问即使带上 Hint,也会被视为「同事务内二次访问同一热点行」,从而导致事务回滚。
·Hint 不跨事务、不跨语句继承,事务结束后自动失效。
四、INDEPENDENT_GROUP 不同放置位置的实际表现
| 放置位置 | 实际效果 |
| 事务第一次访问行 X 的 DML 上 | 行 X 进入独立组,本事务对行 X 的后续访问全部放行 |
| 事务第二次及之后访问行 X 的 DML 上 | Hint 等同于没写:行 X 在第一次访问时已被记录为「非独立组」,本次访问被判为「二次访问同一热点行」,事务回滚 |
| 当前事务不是 TXSQL_FORCE_LOCK 事务 | 解析期 warning + 丢弃,按普通语句处理 |
五、场景1:单事务更新多个不同热点行
适用:需要在一个事务内同时修改多行热点数据(例如批量扣减不同账户余额)。
做法:只在事务的第一条 DML 上加 TXSQL_FORCE_LOCK,后续 DML 不需要再带 Hint。
BEGIN;– ① 第一条 DML 必须带 TXSQL_FORCE_LOCKUPDATE /*+ TXSQL_FORCE_LOCK */ t_account SET balance = balance + 100 WHERE id = 1;– ② 第二条及后续 DML 不需要再带 hint,事务已经处于 force_lock 模式UPDATE t_account SET balance = balance + 100 WHERE id = 2;UPDATE t_account SET balance = balance + 100 WHERE id = 3;COMMIT;
六、场景2:单事务对同一热点行多次访问
适用:需要在一个事务内对同一行热点数据做多次读写(例如先扣减、再校验、再调整)。
做法:在事务首次访问该热点行的那条 DML 上,同时带上 TXSQL_FORCE_LOCK 与 TXSQL_FORCE_LOCK_INDEPENDENT_GROUP;后续访问不再带 Hint。
BEGIN;– ① 首次访问 id=1,必须同时带两个 hintUPDATE /*+ TXSQL_FORCE_LOCK TXSQL_FORCE_LOCK_INDEPENDENT_GROUP */ t_account SET balance = balance + 1 WHERE id = 1;– ② 之后对 id=1 的访问不需要、也不应该再带 INDEPENDENT_GROUPUPDATE t_account SET balance = balance + 1 WHERE id = 1;COMMIT;
七、反例:INDEPENDENT_GROUP 漏在首次访问
以下为错误用法示例,事务会回滚:
BEGIN;– 首次访问 id=1 时漏掉了 INDEPENDENT_GROUPUPDATE /*+ TXSQL_FORCE_LOCK */ t_account SET balance = balance + 1 WHERE id = 1;– 在第二次访问时才补上 INDEPENDENT_GROUP —— 已经太晚– 此时 id=1 已被记录为「非独立组」,本条会被判为「二次访问同一热点行」,事务回滚UPDATE /*+ TXSQL_FORCE_LOCK_INDEPENDENT_GROUP */ t_account SET balance = balance + 1 WHERE id = 1;COMMIT;
八、使用约束
·单事务最多参与到10个热点行(受 undo 页固定持久化区容量限制),超出会回滚事务并打 warning。
·TXSQL_FORCE_LOCK 必须放事务首条 DML;TXSQL_FORCE_LOCK_INDEPENDENT_GROUP 必须放对应热点行的首次访问 DML。放错位置会失效或事务回滚。
·Hint 不会跨事务 / 跨语句继承,每个事务 / 语句都需要重新声明。
注意:说明:
注意:使用功能前建议在测试环境对业务事务进行验证,确认 Hint 已实际生效(可通过 SHOW WARNINGS 排查是否因放置位置错误被忽略)。
九、补充说明
本版本同时优化了热点行冷却时的性能回退问题:通过队首等待者自唤醒、以及基于滑动窗口的冷却机制,解决了热点流量从大变小时不必要的事务延迟。该优化对业务无感知、无需改造。