前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MarsTalk | 给老婆讲懂数据库系列之原子性

MarsTalk | 给老婆讲懂数据库系列之原子性

作者头像
HelloMin
发布2022-08-11 14:32:25
2740
发布2022-08-11 14:32:25
举报
文章被收录于专栏:Pair ProgrammingPair Programming

数据库事务Transaction有四大特点:ACID

  • Atomicity 原子性
  • Consistency 一致性
  • Isolation 隔离性
  • Durability 持久性

本文主要介绍一下Atomicity原子性。

串行场景

假设A、B和C在银行都有存款,存款额分别为:

  • A有500元
  • B有200元
  • C有100元

现在A在ATM机上给B转账200元,然后又在手机客户端上给C转账400元。

一个串行的场景如下:

1. 给B可以成功转账,余额分别为A=300 B=400 C=100

2. 给C转账会失败,因为A的余额少于转账金额

并行场景

刚才是串行执行的场景,没有任何问题,转账B成功,转账A失败,总金额不变(都是900元)。

但是如果两个转账操作是同时进行,由于A的初始金额是500,给C转账的时候不会发现余额不足,一个可能的执行逻辑如下:

1. 给B可以成功转账,余额分别为A=300 B=400 C=100

2. 给A转账成功一半,C增加400,A减400失败

这时候发现银行总存款从900元变成1200元,数据发生了不一致的情况。

一种办法

有人会想到一个办法,转账的时候先做减法,再做加法,这样减法就会失败,就不会执行加法,这样银行总存款就是正确的:

这确实可以解决这个问题,但是如果考虑到可能会由于其他原因(网络、磁盘故障),在减法成功的前提下,最后一步加法失败,还是会导致总存款不一致。

另外一种办法

也许有人想到了另外一种办法,就是如果发现最后A-400失败,可以恢复上一步操作,即让C-400,这样还是可以保证总存款是正确的。

这确实也是一个办法,但是同样如果考虑到可能会由于其他原因(网络、磁盘故障)导致最后恢复上一步操作的时候失败,还是会导致总存款不一致。

原子性

最后发现无论我们怎么设计流程,都无法100%保证数据正确性,根本的原因是:

1. 我们需要做两个操作(对一个数做加法,对另外一个数做减法)

2. 任何一个操作都有可能成功或者失败

3. 我们需要保证数据一致性的前提是:要么两个操作都成功,要么两个操作都失败

这时候就需要用到事务的原子性。

代码语言:javascript
复制
原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。

也就是说我们需要把B账号+200 & A账号-200放到一个事务中执行,要么全部成功,要么全部失败,如下图所示:

1. B账号+200 & A账号-200成功

2. C账号+400 & A账号-400失败

最后银行存款总额保持900元,数据保证了正确性。


Min:Mars本来想一次性把所有概念都抖落清楚,可是发现越写越多,于是决定写成一个短小的系列文章。本文主要介绍了一个概念,这个概念最终在真实的数据库场景中是如何实现的,其实是我更感兴趣的话题,据说Mars会在之后的文章中慢慢道来,那就拭目以待啦~

周中愉快!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pair Programming 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 串行场景
  • 一种办法
  • 另外一种办法
  • 原子性
相关产品与服务
访问管理
访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档