系统的数据一致性到底是在说什么?我到今天才算真明白了

本文探讨了系统数据一致性的重要性,从单体架构到分布式架构的变化带来的新问题。在单体架构中,数据库事务可以确保数据一致性,但在分布式系统中,数据一致性成为挑战。CAP理论解释了在分区容忍性不可忽视的情况下,必须在一致性与可用性之间做出选择。为了解决分布式事务,文章提到了BASE理论和各种解决方案,如两阶段提交、三阶段提交、TCC和基于可靠消息的方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作为一名程序员,你是不是经常在很多场景,例如看博客、聊天吹水等等时候听到这样一个词"系统数据一致性",是不是有时候感觉到了迷糊,不知道这个"系统数据一致性"到底是在说什么?其实,你可能只是不明白这个词,但是你肯定在实际工作中发现、解决过这样的问题。

系统的数据一致性到底是在说什么?我到今天才算真明白了

 

单体架构下系统数据一致性问题

在传统的系统应用中,一般都是使用单体架构来构建系统的。即所有的功能模块都放在一起实现,打成一个WAR包部署在Tomcat中,数据一般存放在关系型数据库中,如MySQL数据库。

系统的数据一致性到底是在说什么?我到今天才算真明白了

 

前面我说过即使这种单体架构的系统也是数据一致性的问题的,举一个电商下单的例子,用户提交完订单,系统,系统在订单表order表中写入订单金额、用户等相关数据,在订单明细order_item表中写入商品价格、购买的数量等数据,最后更新商品的库存sku信息。用户下单成功之后,系统操作了order、order_item、sku这三个数据表,对于这三个表的操作无论成功与失败,都应该是原子的,操作成功则都要成功,失败则都要一起失败。不然就会出现脏数据,数据一致性被破坏。

1、 如果操作order和order_item表成功,操作sku表失败,则会导致本应该扣减的库存没有扣减,则商品有可能出现超卖。

2、如果操作order和order_item表失败,操作sku表成功,则会导致本不应该扣减的库存扣减了,则商品有可能出现少卖。

3、如果操作order和sku表成功,order_item操作失败,则这个订单数据丢失,订单后续的操作肯定也是操作不了了。

上面只是简单的举了三种可能出现的情况,也可能会有其他的情况发生。那我们怎么避免这些情况的发生呢?其实这种问题稍微有的开发经验的同学都会想到解决方案,那就是使用数据库的事务,事务的原子性保证上述的步骤成功则一起成功,失败则一起失败。

BEGIN;
INSERT INTO order;
INSERT INTO order_item;
UPDATE sku;
COMMIT; # ROLLBACK

在单体架构的系统下解决内部模块的数据一致性的问题,用数据库的ACID特性就能保证。

单体架构的优点就是相对分布式来说开发简单,功能可以集中管理,模块之间通信没有损耗。但随着业务越来越复杂、需求越来越庞大,人们对系统响应时间、吞吐量和出现故障的时候的系统可用性的要求也越来越高!传统的单体架构系统在这种情况下暴露的缺点也越来越多,人们开始寻求转变。既然部署在一个服务器上的单体架构系统搞不定,那就多部署几台,即用多台单机节点组成集群,再用负载均衡向外提供服务。

系统的数据一致性到底是在说什么?我到今天才算真明白了

 

但是这样做还是解决不了单体架构存在的一些问题:

  • 只能使用同种语言开发,不能针对不同业务场景利用不同语言的优势开发对应的模块。
  • 系统模块耦合性太强,系统中某一个模块出现问题,例如高并发、大数据场景或者出现bug,整个系统都会受到牵连。
  • 某个模块发布,整个系统都要停机发布,系统所有模块都不能对外提供服务,这样无法快速响应市场需求。
  • 集群负担大,如果想要集群,只能
### 事务的基本概念 事务是一组逻辑上的操作集合,这些操作作为一个整体被执行。如果该组内的任何一个操作失败,则整个事务将被视为未完成并回滚至初始状态[^1]。 在数据库领域中,这种机制被称为数据库事务。它确保了一组相关联的操作能够按照预期顺利完成或者完全撤销,从而维护数据的一致性和可靠性。 --- ### 数据库事务的 ACID 特性详解 #### 原子性 (Atomicity) 原子性表示事务是一个不可分割的工作单位。这意味着在一个事务中的所有操作都必须成功执行;如果有任何单个操作失败,则整个事务都将被取消,并且回退到其最初的状态[^4]。通过这种方式可以防止部分更新导致的数据不一致问题。 ```sql BEGIN TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; -- 减少账户余额 INSERT INTO transactions VALUES ('withdraw', 1, 100); -- 记录交易日志 COMMIT; ``` 上述 SQL 脚本展示了一个简单的银行取款场景。只有当两个语句均无误时才会提交更改;否则会触发 ROLLBACK 来恢复原始数据。 #### 一致性 (Consistency) 一致性保证了事务前后数据库处于合法状态下。具体来说,在每次事务完成后,所有的业务规则都应该得到满足,而不会违反预定义的数据完整性约束条件[^2]。换句话说,无论何时查看数据库的内容,它们总是符合既定的标准和关系模型的要求。 例如,假设有一个库存管理系统规定商品数量不能为负数。那么涉及减少库存量的事务就必须严格遵循这一原则——即使出现了意外情况也不会让实际存储数值低于零。 #### 隔离性 (Isolation) 隔离性意味着多个并发运行的事务彼此独立运作互不影响。尽管可能存在多用户同时访问相同资源的情况,但从单一用户的视角来看,他的查询或修改似乎是在没有任何干扰的情况下单独进行的[^3]。实现此特性的常用方法之一是采用锁机制来控制共享对象之间的竞争状况。 考虑下面的例子: | 时间 | 用户 A 的动作 | 用户 B 的动作 | |------|----------------------------------|-----------------------------------| | T1 | 开始新事务 | | | T2 | 查询产品 X 当前价格 | | | T3 | 更新产品 X 新的价格 | 开启另一个事务 | | T4 | 提交自己的改动 | 尝试读取最新版本的产品 X 定价 | 如果没有良好的隔离措施的话,可能会造成脏读现象(即 UserB 可能看到尚未最终确认的新值)。然而借助适当级别的锁定策略则可有效规避此类风险。 #### 持久性 (Durability) 一旦事务被正式认可并通过 COMMIT 操作保存下来以后,即便系统遭遇崩溃或其他异常事件也不应丢失已处理的结果。持久化通常依赖于磁盘文件或者其他非易失介质作为后备支持手段以确保存储的安全可靠程度达到最高标准。 比如 MySQL 使用 redo log 和 binlog 技术保障已经提交记录即使面对服务器重启也能完好保留。 --- ### 总结 综上所述,事务及其所具备的 ACID 属性共同构成了现代关系型数据库管理系统的基石。正是由于有了这样一套完善的理论框架指导实践应用开发工作才得以更加稳健高效地开展起来。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值