Sharding-JDBC 的事务处理小结
Sharding-JDBC 是由当当网推出的一款开源的分布式数据库中间件。它以 JDBC 的形式嵌入到应用程序中,无需额外部署。Sharding-JDBC 实现了分库分表、读写分离和分布式主键功能,并初步实现了柔性事务。
本文主要介绍 Sharding-JDBC 的事务处理。
Overview
Sharding-JDBC 由于性能方面的考量,决定不支持强一致性分布式事务。我们已明确规划线路图,未来会支持最终一致性的柔性事务。
- 默认使用 “弱XA” 事务
- 可选使用柔性事务:
- BED(最大努力送达型)事务
- TCC(补偿型)事务
“弱XA”事务
之所以加引号,是因为这个和 MySQL 的 XA 其实没有关系。
它的实现是很自然的:
- Prepare 阶段(执行
SQL)过程遇到异常,则中止当前事务,对所有分库上的事务连接执行
conn.rollback()
- Commit
阶段(提交事务)时对所有分库依次(其实可以并行)做
conn.commit()
;如果某个事务连接 commit 时抛出异常,由于无法回滚其他连接,所以仅仅是收集起来报给调用者,交由用户处理。不影响其他分库 commit。
文档中对使用注意事项也写的很明确:
不支持因网络、硬件异常导致的跨库事务。例如:同一事务中,跨两个库更新,更新完毕后、未提交之前,第一个库死机,则只有第二个库数据提交。
柔性事务
分布式场景下传统数据库 ACID 无法满足业务的性能要求,所以诞生了 BASE 理论。BASE是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的简写,其中软状态是指允许系统中的数据存在中间状态。
Sharding-JDBC 的柔性事务是需要调用者显式开启的。以 BED
事务为例,客户需要先通过柔性事务管理器创建出 BEDSoftTransaction
对象,然后使用 begin()
开始柔性事务。
BED(最大努力送达型)事务
用户保证该数据库的操作最终一定可以成功,所以通过最大努力反复尝试。
结合上图,执行过程可以分为 4 种情况:
- 同步执行成功
- 同步执行失败,同步重试成功
- 同步执行失败,同步重试失败,异步重试成功
- 同步执行失败,同步重试失败,异步重试失败,事务日志保留(人工介入处理)
BED 不保证 exactly once,所以使用 BED 的 SQL
需要满足幂等性,例如不能用 UPDATE SET x = x + 1
这样的
SQL。
TCC(补偿型)事务
目前还在规划中,没有实现。