在数据库中新建一个字段并且设置为索引列,还有删除整张表的数据,类似这些操作都是一系列操作的组合,执行后不能出现中间状态,也就是不会出现新建了字段却不是索引的情况,也不会出现只有一部分数据被删除的情况。这种保证是事务在发挥作用,虽然我们没有使用begin-transaction-commit来执行命令。

既然事务是一系列操作的组合,那两个事务的多个操作如何正确顺序执行和如何高效执行就是关键了。这就要说说事务的ACID原则了,ACID指的是原子性、一致性、隔离性、持久性。

假设有这么一个场景,用户A的初始余额是100元,用户B的初始余额是0元,用户A需要向用户B转账100元。这个场景事实上是分二步执行的,第一步是扣除用户A账号上的100元,第二步是给用户B账号的余额增加100元。最终状态是用户A余额为0元,用户B的余额为100元。

不过,在执行扣除和增加这两步时随时可能发生错误。比如业务属性不匹配,用户B的账号有敏感操作被冻结了,无法更新,所以要恢复到初始状态。又比如系统崩溃了,所以系统重启时要首先进入安全模式,已提交的事务要继续完成,未提交的事务要取消掉。这样才能保证事务操作要么全部成功,要么全部失败。

那如何恢复到初始状态或者取消未提交的事务呢?

执行操作前把之前的值备份下来,不就可以借助备份进行递向操作了嘛?没错,在数据库的体现就是Undo log回滚段。

前面描述的事务场景可能过于简单,我们考虑这么一件事,用户C在刚才的事务执行过程中给用户B成功转入了300元,也就是说同时有多个事务在执行。不幸的是,刚才的事务被回滚了,用户B的余额最终被更新成了0元。后果就是用户C的转入操作好像没发生过一样,成了一笔坏账。

这个问题的原因是原子性不能保证可见性,当前事务看不到其它事务提交的结果,这才导致了数据的不一致。事实上可以使用排它锁来保证一致性。对账号A和账号B这两个资源进行加锁,事务获得锁才能执行,执行完才释放锁。这样事务是串行化执行的,当前事务肯定是能看到前一个事务提交结果的,数据一定是强一致性的。

使用到锁就要考虑死锁问题了,死锁问题说的是两个进程在不同方向抢占相同的共享资源。我们可以通过碰撞检测来发现系统中是否存在死锁,每个进程都记录已拥有和等待中的锁,如果出现了回环,说明有死锁。解决死锁的一般办法是锁等待超时。

使用锁时除了死锁还要考虑性能问题,排它锁是简单粗暴的方法,但是性能有点不忍直视。这时就得考虑一些优化策略了,比如减少锁的覆盖范围、减少锁的持有时间、使用并行代替串行。

数据库的设计大师正是考虑到这些,才引入了事务隔离性。

第一种事务隔离性是序列化读写。所有的事务放入到队列中依次执行,比如读写-写读-读读-写写。

第二种是读已提交。当前事务只能读取到其他事务已提交的结果,这种隔离下读-读、读-写都是可以并行执行的,因为当前事务依赖的数据是前一个写操作的结果。

第三种是可重复读。在同一个事务中,多次读取到的结果是一致的。这种隔离下读-读、读-写都是可以并行执行的。

第四种是读未提交。当前事务能看到其他事务还没有提交的中间状态,这种隔离下,只有写锁,读是不加锁的,所以除了写-写,读-写、写-读、读-读都是可以并行的。代价是出现脏读。

透过这四种事务隔离,明显能看到读写锁带来的收益,那能不能再优化下呢?

答案是可以的,秘决就是多版本并发控制MVCC,它的本质是写时复制Copy on write。行记录每次修改时都会产生一个快照和一个版本号,版本号是单向增长的逻辑时间戳,用来表示先后顺序。而读操作只会读取到早于当前事务版本的记录。显然,这种技巧非常适合读多写少的场景,而且能达到读未提交的并发度,隔离级别更好。

既然读-写、写-读、读-读都是可以并行的,写-写也能并行就更好了。

我们先来看下写-写并行会有什么问题。假设用户A要给用户B转账100元,用户B也要给用户A转账100元,考虑到事务间原子操作顺序的不可见性,用户A的余额可能会在原来基础上增加了100元,银行得损失100元。针对这种情况,需要借助乐观锁的思想来保证数据的一致性,针对同一行记录,只有高版本的事务更新能成功,低版本的事务更新得回滚掉。缺点是并发高时失败率高,需要不断重试。

除了事务隔离,数据库设计的大师为了提高并发效率,还做了很多优化。比如每次写操作并不直接持久化到磁盘中,而是暂时存放在易丢失的内存中,然后通过一定的机制异步同步到磁盘。这样就保证了数据的持久性,确保事务一旦提交,操作肯定会固化到数据库中。类似生活中这种场景,餐馆老板娘很忙的时候,就把每笔交易写在黑板上,当老板娘空闲、黑板写满或者餐馆打烊后再整理写入到账本中。

谈谈数据库的事务ACID的更多相关文章

  1. 数据库零基础之---了解数据库的事务[ACID]

    事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 我们先举一个例子来描述一下事务: 假设要张三通过银行给李四进行转账1000元钱,张三原有余额10000元整,李四有人民币 ...

  2. 数据库事务ACID详解(转载)

    转载自:http://blog.csdn.net/shuaihj/article/details/14163713 谈谈数据库的ACID 一.事务 定义:所谓事务,它是一个操作序列,这些操作要么都执行 ...

  3. 【转】数据库事务ACID以及事务隔离

      本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指 ...

  4. 数据库中事务的四大特性(ACID)

    本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务 ...

  5. 【数据库】事务,ACID,CAP和一致性

    什么是事务 事务是指由一系列数据库操作组成的一个完整的逻辑过程,这个过程中的所有操作要么都成功,要么都不成功.比如:常见的例子就是银行转账的例子,一次转账操作会包含多个数据库操作,而这些数据库操作需要 ...

  6. 带你了解数据库中事务的ACID特性

    前言 前面我们介绍过数据库中 带你了解数据库中JOIN的用法 与 带你了解数据库中group by的用法的相关用法.本章节主要来介绍下数据库中一个非常重要的知识点事务,也是我们项目中或面试中经常会遇到 ...

  7. 谈谈数据库的ACID

    一.事务 定义:所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位. 准备工作:为了说明事务的ACID原理,我们使用银行账户及资金管理的案例进行分析. // 创建 ...

  8. spring 传播行为与数据库事务ACID

    数据库事务ACID特性 数据库事务正确执行的4个基础要素是原子性(Atomicity).一致性(Consistency).隔离性(Isolation)和持久性(Durability). •原子性:整个 ...

  9. 数据库事务ACID特性(原子性、一致性、隔离性、持久性)

    ACID特性: 原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability) 原子性:一个事务必须被视为一个不可分割的最小工作单元,整个 ...

随机推荐

  1. 【经验分享】用adb揪出安卓APP弹窗广告的原形

    背景 相信不少安卓用户中过影子弹窗广告的困扰,这种推广APP本体在后台运行,而且可以在其他APP上弹出覆盖广告,一不小心就会误操作,点击广告或者下载APP,着实令人恶心. 以前的广告软件只在通知栏会推 ...

  2. 想在java接口自动化里用上Python的requests?这样做就可以了

    相信现在很多的公司自动化测试重点都在接口层,因为接口测试更加接近代码底层,相对于UI自动化,接口自动化有着开发更快.覆盖更全.回报率高等优点. 接口自动化代码实现不难,本质上就是代码模拟发送请求,然后 ...

  3. 分数运算(gcd)

    时间限制 1000 ms 内存限制 32768 KB 代码长度限制 100 KB 判断程序 Standard (来自 小小) 题目描述 计算机中采用浮点数表示所有实数,但这意味着精度丢失.例如无法精确 ...

  4. 详细分析链表中的递归性质(Java 实现)

    目录 链表中的递归性质 前言 LeetCode 上关于链表的一道问题 203 号题目 移除链表中的元素 递归的基本概念与示例 链表天然的递归性 小结 链表中的递归性质 前言 在前面的 链表的数据结构的 ...

  5. Redis6.0.6集群服务搭建

    实现目标 一台主机上搭建3主3从高可用redis集群 环境 Linux :CentOS7 Redis : 6.0.6 准备工作 1.查看是否有安装wget命令,如果没有安装使用yum命令安装wgt命令 ...

  6. Linux下安装Sublime Text 3 及使用快捷方式

    1.添加sublime text3的仓库 首先按下快捷键ctrl+alt+t打开终端: 在终端输入:sudo add-apt-repository ppa:webupd8team/sublime-te ...

  7. Mysql主从分离与双机热备超详细配置

    一.概述 本例是在Windows环境,基于一台已经安装好的Mysql57,在本机安装第二台Mysql57服务. 读完本篇内容,你可以了解到Mysql的主从分离与双机热备的知识,以及配置期间问题的解决方 ...

  8. Redis统计访问量方法

    1.统计客户忘问量 2.查询某位ID客户是否登录 一亿用户,统计数据10M左右,比较省空间 set usercount 0 设置一个变量,用于记录客户访问量setbit usercount 2 0   ...

  9. DoS拒绝服务-工具使用hping3、nping等(四)

    Hping3几乎可以定制发送任何tcp/ip数据包,用于测试fw,端口扫描,性能测试 Syn Flood – hping3 -c 1000 -d 120 -S -w 64 -p 80 --flood ...

  10. 第11课 - enum, sizeof, typedef 分析

    第11课 - enum, sizeof, typedef 分析 1. enum介绍 (1)enum是C语言中的一种自定义类型,和struct.union地位相同,格式如下: // enum每个值的最后 ...