事务、一致性与分库分表
Category
database / 事务与扩展。节点定位:把事务(局部正确)、一致性(跨链路收敛)、分库分表(规模扩展)拆成三层问题分别决策——按价值分层,扩展手段最后才动。
Definition
这几个词常常被放在一起谈,但它们解决的是不同层面的问题。事务讨论的是单次状态变化如何保持局部正确,一致性讨论的是跨链路和跨系统最终如何收敛,分库分表讨论的是当数据规模和负载上来以后,怎样继续扩展而不把系统拖垮。把这三件事混成一句“以后分库分表就好了”或“上事务就安全了”,通常只会让问题更模糊。
真正应该先问的是:哪类状态必须强保证,哪类状态允许延后收敛,以及这些代价值不值得为当前业务承担。
Problem
三件事混成一句「上事务就安全」「以后分库分表就好了」,账一定算错:事务只保单个数据库边界内的局部正确;状态跨出边界后,靠的是权威边界、幂等与补偿,不是更大的事务;分库分表是规模瓶颈到来时的扩展手段,不是性能神药——过早分片,是把索引和查询模型的简单问题变成路由、迁移和审计的复杂问题。
事务真正值钱的地方
事务的价值从来不是“高级”,而是让一组本应一起成功或一起失败的变化在局部边界内可控。对于这些场景,它通常非常重要:
- 货币扣减与道具发放
- 订单确认与发货记录
- 背包变更与日志写入
- 交易状态流转
这类问题一旦做坏,后面补偿和追责成本极高,所以局部事务边界往往值得被认真设计。
为什么不能指望事务解决所有一致性问题
一旦状态跨出了单个数据库、单个服务或单个存储边界,事务成本会迅速上升。很多真实链路会变成:
- 这边资产写成功了,那边排行更新超时了
- 订单确认了,但通知和日志还没落地
- 服务 A 提交了,本该联动的服务 B 没跟上
这时系统真正需要的,往往不是更大的事务,而是更清楚的权威边界、幂等、补偿和可恢复设计。
一致性强度应该按价值分层
更现实的做法通常是把一致性分层看待:
- 高价值资产和订单链路,优先保证最终正确与可审计
- 主流程周边的派生数据,可以接受延迟收敛
- 报表、统计和低价值副本,允许更宽松的最终一致
这样做不是妥协,而是避免把所有链路都按最高强度设计,最后成本和延迟一起失控。
分库分表为什么常被过早讨论
很多团队在数据量还没真正成为瓶颈时,就开始热衷讨论分库分表。问题在于,分库分表不是性能神药,它会立刻带来这些新成本:
- 主键和路由规则复杂化
- 跨分片查询和事务变重
- 数据迁移和扩容更难
- 排障和运维复杂度上升
如果当前问题其实是索引设计差、冷热数据混杂、查询模式不合理,过早分库分表只是在把简单问题变成复杂问题。
什么时候它会变成现实问题
分库分表真正会进入主议题,通常是在这些时候:
- 单表或单库已经接近真实瓶颈
- 热点数据和长尾数据差异极大
- 单机资源和维护窗口难以承受
- 合服、跨区和多地域带来明确扩展需求
这时再讨论分片,重点也不该是“怎么拆表名”,而是数据路由、扩容策略和迁移成本。
一个更稳妥的处理顺序
比较稳妥的顺序通常是:
- 先明确权威数据边界和事务边界。
- 再根据价值分层确定一致性要求。
- 最后在确实需要时再引入分库分表和更复杂的扩展策略。
这个顺序的意义在于,不让扩展策略反过来主导业务边界。
常见误区
最常见的错误,是把事务当成所有一致性问题的统一解法。第二类错误,是还没把权威边界和查询模型理顺,就急着分库分表。第三类错误,是分片以后只看吞吐提升,不看跨分片查询、迁移、审计和恢复成本,结果系统虽然更分散,却更难治理。
Used By
资产链路的事务边界设计(货币扣减、订单确认、发奖记录);一致性分层的评审口径(资产最终正确、派生延迟收敛、报表宽松一致);扩容规划里判断分库分表的时点与替代手段。
- KBEngine(commit
0bc93d5):事务边界落在「一次表同步」上——DB 任务挂在自有线程池任务基类上(kbe/src/lib/db_interface/db_tasks.h:21),写库任务的粒度是实体表(DBTaskSyncTable(EntityTables*, EntityTable*),同文件:48-51)。跨表的组合要么在业务层自己兜,要么只能靠补偿——先把粒度定清楚,再谈要不要引入跨表事务
Related
关系链:权威源与事务边界 → 一致性按价值分层 → 分库分表(规模真到才动)。上游:状态分类与权威源(01)、存储分层(02)。下游:数据同步(04,副本语义与重建)、server 树的结算权威(跨服务一致性的玩法侧)。
Reference
本页为工程经验归纳,无单一外部出处。