什么是事务的一致性?一致性和原子性的区别是什么?

什么是事务的一致性?一致性和原子性的区别是什么?关于事务的一致性 数据库系统概念 中是这样描述的第二段说的三个特性是指原子性 隔离性 持久性 就算这样 相信大家也是懵懵的 我也是 所以才会写下这篇博客 看到别的博客说 一致性是事务的最终目的 原子性 隔离性 持久性都是为了实现一致性 在这里 我打算验证一番 怎么验证呢 假设 这个事务系统如果是由我们来设计的话 首先 场景是这样的 小范转 100 块钱给小黄 那么这个

(PS:黄色字体为二次修改的内容)

关于事务的一致性,《数据库系统概念》中是这样描述的

什么是事务的一致性?一致性和原子性的区别是什么?

第二段说的三个特性是指原子性、隔离性、持久性。

就算这样,相信大家也是懵懵的,我也是,所以才会写下这篇博客。

看到别的博客说,一致性是事务的最终目的,原子性、隔离性、持久性都是为了实现一致性。

在这里,我打算验证一番。

怎么验证呢?

假设,这个事务系统如果是由我们来设计的话。

首先,场景是这样的,小范转100块钱给小黄,那么这个事务系统必须要保证小范扣了100块钱,而且小黄也必须要加了100块钱。

这个我们要怎么保证呢?

有了,我们可以先用一本本子记下来,小范扣100块钱,小黄加100块钱,然后,我们再根据本子上写的,顺序执行,这样的话,小范或者小黄就没法耍赖了。

OK,那么我们现在就开干,把这个事务系统开发出来,下面是伪代码:

//事务系统 abstract class transaction{ void transaction(){ /* todo:将所有操作写进日志 * args: 事务名称, 事务操作, 事务写入状态(0 未写完 1已写完) */ setLog("小范转100块钱给小黄", "小范-100", 0); setLog("小范转100块钱给小黄", "小黄+100", 1); //获取日志 Log logs = getLog("小范转100块钱给小黄"); //解析日志,获取操作事件 Event events = parseLog(logs); //执行操作并回写日志状态标记该事务已完成 doEvent(events, logs); } }

OK,系统开发出来了,我们把它应用上去跑起来试下。

但是,可能是因为计算机内存不够,系统跑到一半,闪退了。。。

也就是doEvent的时候,小范扣了100块钱,这个时候闪退了。。。

上数据库一看,完了,小范已经扣了100,但是小黄并没有增加100,事务也没有执行下去。

所以我们这个事务系统是有问题的,我们的事务系统,应该要保证小范扣100,而且小黄也要加100,我们姑且称这种状态为一致性,因为我们要保证这两个操作对数据而言是一致的嘛。

从目前来看,我们这个事务系统,没有完全实现一致性,那如果发生了这种状况,系统闪退停机等等异常情况,我们该怎么处理,才能保证一致性呢?

有了,我们可以在日志中多加一个状态,用来标记该操作有没有执行,然后用一个定时器,每隔几秒找出日志中没有完成的事务,把它执行完,这样一来,就能保证小范扣了100,小黄加了100了,哪怕中途停机了,也能用定时器把事务执行完。

就这样测试了十来次,结果跟操作都一致,确实能保证一致性了,就正式给用上生产环境了。

可是才不到一天,就出问题了,怎么呢?有个业务,小张向老李转账300元,可是小张的账户上只有298,该死的初级程序员又没有对小张的金额作校验,直接就给执行了。

这下小张的账户余额变成了-2,老李的账户变成了300。闹了个大笑话。

这虽然主要责任不在我们开发的事务系统,但是,我们也要做处理,也就是在小张的余额做加减的时候,减成了负数,这个时候程序应该需要抛出异常的,不能让程序再执行下去了,所以,这就需要我们的事务系统,可以在执行到一半的时候,回滚到初始状态。

也就是说,如果同一个事务中,有操作ABC三个顺序操作,操作A成功了,操作B失败了,那这操作C还要执行吗?当然不能,这种情况,B失败了,我们就只能把A给回滚到操作之前。

这样一来,我们这个事务系统就是,要么事务都完成,要么事务都不完成,我们姑且就把这个叫做原子性吧。

增加了原子性的功能后,事务系统又开始跑了。

过了几天,又出问题了,怎么呢?原来啊,小范有300块钱,小张向小范转了500块钱,事务还没操作完呢,小刘又给小范转了300块钱,这样一来,问题就来了,小张给小范转500,本应该事务结束的时候小范有800块钱,可是小刘又给小范转了300,还是用小范原有的300去增加的,这样一来,小刘的事务结束,小范就有600块钱,小张的事务执行完,把800写回给小范,接着,小刘的事务也执行完,把600写回给小范,导致最终小范账上只有600块钱,小张的500被吞了。

这样,数据完全混乱了。问题出在哪呢?在于小张事务执行的时候,读取到小范有300,事务没完,小刘也读取到小范有300,这样就错乱了,我们应该要让小张在转账的时候,小刘要等小张转完了,才能转。这样,才能解决掉数据混乱的问题,我们,姑且把这个叫做隔离性。

隔离性修复完之后,项目又开始运作了,事务系统运行了很长一段时间,也没有出现问题。

到这里,验证就结束了,上面写日志的行为其实就是事务的持久性,也可以看到,上面出现的隔离性、原子性、持久性,也都是为了彻底实现一致性而产生的。

所以,总的来说,一致性是一个比较笼统的概念,是事务的基础,一致性和原子性的区别就是,原子性强调的是操作的完整,要么都成功、要么都不成功,而一致性包含的比较多,数据的一致性啊等等。

不过其实,我觉得一致性不应该跟原子性、隔离性、持久性放在一起,因为这三个都是为了实现一致性,如果有大佬知道,麻烦跟我说下原因。

到这,本文就结束了,写的真的不是很好,以后,要是我对事务一致性、原子性有了新的理解,我会再回来修改的,也欢迎各位大佬留言或者私聊我,给我写关于一致性的启发。

知乎上有个回答也是写的蛮好的,大家可以看看,https://www.zhihu.com/question/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/210835.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午11:48
下一篇 2026年3月18日 下午11:49


相关推荐

  • 永恒之蓝病毒解决方法蠕虫_永恒之蓝病毒解决方法

    永恒之蓝病毒解决方法蠕虫_永恒之蓝病毒解决方法辛亏“永恒之蓝”爆发在周末,绝大部分员工在家休息,为我们避免内网病毒爆发赢取了时间,整个周末一直加固已有系统和准备应急预案,避免周一发生大规模“永恒之蓝”在内部大面积爆发的可能。整体措施和预防传染病的原理类似:控制传染源、切断传播途径,保护易感人群。1控制传染源:所有的办公电脑开机前都必须网络隔离,所有计算机严禁插入U盘,一旦出现感染电脑,直接拔电源。就内网环境而言,一旦出现一例,大概率爆…

    2022年10月10日
    6
  • Linux TSO流程分析

    Linux TSO流程分析1 TSO transimitseg 是针对 tcp 而言的 是指协议栈可以将 tcp 分段的操作 offload 到硬件的能力 本身需要硬件的支持 当网卡具有 TSO 能力时 上层协议栈可以直接下发一个超过 MTU 数据包 而把数据包拆分的动作交给硬件去做 节省 cpu 资源 除了 TSO 内核还有一个 GSO GSO 不区分协议类型 GSO 默认是开启的 GSO 是在软件上实现的一种延迟分段的技术 相比 TSO GSO 最终还是需要协议栈自己完成分段的处理 即使网卡没有 TSO 能力 传输层依然可以封装一个超过 M

    2026年3月18日
    2
  • Centos7.2安装Nginx实现负载平衡

    Centos7.2安装Nginx实现负载平衡

    2022年2月23日
    56
  • GetType和typeof的区别 以及一个小实例

    GetType和typeof的区别 以及一个小实例

    2021年8月15日
    59
  • nbtscan ip地址

    nbtscan ip地址查找网络 192 168 1 0 中 netbios 名字信息 对应命令如下 nbtscan192 168 1 1 254 找到有 netbios 名字后 可以使用如下的命令查看这些主机运行的服务 nbtscan hv192 168 1 1 254 转载于 https www cnblogs com seasonsstory p 3468839 html

    2026年3月26日
    2
  • 2021-IP地址详解02「建议收藏」

    2021-IP地址详解02「建议收藏」网络域网:一般称为内网单局域网的构成:交换机,网线,PC()交换机:用来组件内网的局域网的设备ip地址ip地址就是一个唯一的标识,是一段网络编码(二进制)由32位构成11010010.01001001.10001100.00000110=210.73.140.6ip地址的形式:X.X.X.XX的范围:0-255子网掩码局域网通信规则:在同一局域网中,所有的IP必须在同一网段中才能互通通信!IP地址构成:网络位:网络位+主机位(网络位相同的IP地址,位同一网段)

    2022年6月24日
    71

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号