mysql的ACID的理解
这是在网上copy下来的ACID的概念,可以直接跳过看后面:
1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
其中,原子性和持久性的概念比较好理解。但是最近发现老是把一致性和隔离性混淆。
个人理解,隔离性主要是针对读操作的。在不同事务之间,读操作隔离。比如另一个事务对数据修改后,会不会影响当前事务的读操作,要不要读到更新后的数据。
一致性,主要强调的是数据的更新是不是“正确”,即,是不是符合我们的预期,这个和读操作应该是要分开看待的,这里应该只强调写操作。
造成我对这俩个概念的混淆的原因是,在java的并发编程中,我们关注的似乎只有一致性,没听说过java并发编程中有什么隔离性。造成这个的原因是,我们使用锁,或者volition来保证数据的读取是“正确”的,这种“正确”性的保证是通过“排他锁“(这里加引号是因为严格来说,和排它锁可能会有轻微的区别,比如cpu的缓存锁,缓存失效机制,但是效果上还是有排他的效果)来保证的。这种锁机制,是比mysql的MVCC,或者读锁更加严格的,也就是说在java并发编程中本质上是没有读锁(或者乐观锁)这种概念的,就算是ReentrantReadWriteLock ,也是一种对mysql的读写锁的仿制,在java的底层是不存在这种东西的。
而mysql中所强调的一致性,就和java并发编程中的一致性基本是一致的了,都是通过排他锁来保证的,所以在对俩者进行编程时,他们俩者的思路是互通的,是可以相互借鉴的。
mysql为了增加并发量,引入了乐观锁,MVCC这种概念,但是也带来了隔离的问题,即因为没有排它的强制性保证,就会出现读和写并发的场景,那么就需要考虑,在俩者并发的场景下,读操作到底该做什么样约束的问题。相反,在java并发编程中,可以理解为,在排它的保证下,是不会出现读和写并发的存在的场景的,也就不会有隔离性的问题。(大家可以想一个java中的lock,还有无锁算法中依赖的CAS底层也会有lock前缀的指令)。
最后,当认识到这些问题的时候,我们在写sql的时候有什么借鉴的意义呢?
个人意见:
1.把不必要引入的隔离性问题,也就是读操作,可以省掉的就省掉。比如 我们要并发的对数据库中一条记录的值进行加一操作。也许可以先select出它的值,然后在java程序中+1,然后再update回去,为了防止并发带来的一致性问题,可以在update的where条件中带上变量的原值。 但是,如果直接update ... set variable= variable +1 这样呢,这样的话,就把读操作,也就是隔离性的问题消除了,全部都转化成了写操作,也就是一致性的问题了,而mysql使用排他策略来进行写,在这种场景下是可以保证一致性的。
2.我们在考虑要不要加事务,要什么样的隔离级别的时候,思路就会更加的清晰。在考虑隔离性的时候,我们首先就知道它强调的是读的操作,那首先就专心考虑我们对读的要求,而不会被其他操作所干扰。
其次,我们需要考虑我们对读回的值做了什么计算,然后是怎样把计算的结果又更新到数据库中的。那么,由于读得到的数据不一定是”正确的“,我们的写操作是否需要加一致性的校验(比如在where条件中加上预期的原值)。
举个例子:还是刚刚的对一个记录并发的加一,假设我们使用先select,然后update的方法,而且我们一个操作单元是多条记录。
首先,由于我们的操作单元是多条记录,所以我们需要原子性,即这批数据要么全部成功,要么全部失败,所以我们对这多次的select,update操作加上了事务。
然后,我们的select应该使用什么样的隔离级别呢?
首先考虑下可重复读,在这种隔离级别下,很有可能读到”不正确“的数据,即别的事务提交了对这个值的修改,但是我们在当前事务中读到的仍然是老的数据,那么导致计算出来的结果肯定是”不正确“的。
然后我们考虑下提交读,那么在这种隔离级别下,不会出现刚刚说的问题了,但是,由于并发的问题,在我们读完后,可能另一个事务提交了对这条记录的修改。这又造成了当前事务中计算结果的错误。
最后,是读未提交,在这种级别下,面临的就是另外一个事务在更新后,然后又回滚所造成的问题了。
那么可以发现,这三种隔离级别都没法满足我们的要求,所以,就会发现,原来我们对隔离性其实没什么必须的要求,我们这里需要的,只是数据一致性的要求。为什么我没有说串行化的隔离级别呢,因为这种隔离级别下,所有的操作都是排他的,是不存在隔离性的问题的。
上面举的这俩个例子都很简单,我们实际的场景也许会比这复杂的多,但是,如果理解了上面说的隔离性和一致性到底指的是什么,我觉得在面对复杂场景时,是可以缕出一条很好的解决思路的。
mysql的ACID的理解的更多相关文章
- 对事务的特性ACID的理解
对事务的特性ACID的理解 数据库的事务必须具备ACID特性,ACID是指 Atomicity(原子性).Consistensy(一致性).Isolation(隔离型)和Durability(持久性) ...
- MySQL的COUNT()函数理解
MySQL的COUNT()函数理解 标签(空格分隔): MySQL5.7 COUNT()函数 探讨 写在前面的话 细心的朋友会在平时工作和学习中,可以看到MySQL的COUNT()函数有多种不同的参数 ...
- java面试一日一题:讲对mysql的MVCC的理解
问题:请讲下对mysql中MVCC的理解 分析:这个问题要回答的是对MVCC的理解,以及MVCC解决了什么问题这几个方面入手. 回答要点: 主要从以下几点去考虑, 1.什么是MVCC? 2.MVCC用 ...
- mysql 执行计划的理解
1.执行计划就是在sql语句之前加上explain,使用desc 也可以.2.desc有两个选项extended和partitions,desc extended 将原sql语句进行优化,通过show ...
- SQL Server Mysql 对null值理解的不同
在说到对null值的理解主要是用unique来体现的.也是说null在unique约束看来是一个值还是多个值的问题. 还是开始实验吧. MYSQL create table t(x int ,cons ...
- ★ MYSQL隔离级别 通俗理解 + mysql、oracle默认事务隔离级别
★ 脏读 : 读取了前一事务 未提交 的数据 ; 不可重复读 : 读取了前一事务 提交 的数据: ★ 幻读 与 不可重复读 common :都是读取了另一条已经提交的事务(这点与脏读不 ...
- mysql 事物ACID和隔离级别
⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则 ...
- 对于事务ACID的理解
ACID,即以下四点: 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生. 一致性(Consistency) 事务前后数据的完整性必须保持一致 ...
- MySql优化相关概念的理解笔记
MySQL架构 查询执行流程 查询执行的流程是怎样的: 连接1.1客户端发起一条Query请求,监听客户端的‘连接管理模块’接收请求1.2将请求转发到‘连接进/线程模块’1.3调用‘用户模块’来进行授 ...
随机推荐
- try-catch-finally 与返回值的修改
先看一段java代码,func返回值为int: public static int func() { int result = 0; try { result = 1; return result; ...
- 关于pycharm有时候提取不了form表单POST提交的数据
1.有可能标签没有name属性 2.name属性要放在第一个位置,放在末尾有时候会出现BUG导致识别不出,提取的值为None.
- poj2886(线段树求序列第k小)
题目链接:https://vjudge.net/problem/POJ-2886 题意:n个人围成一个圈,每个人有姓名s和权值val两个属性,第一轮序号为k的人退出,并根据其val指定下一个人,val ...
- Python开发【第九篇】:协程、异步IO
协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程,协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回 ...
- c/c++一维数组简单介绍
定义:同一种类型数据的集合 通俗的讲就是,将多个同一种类型的数据按一定的内存顺序写在一起. 注意我的几个关键字“多个”,“同一种”,“一定的内存顺序”.如果理解了这几个关键词,说明你的数组已经掌握了. ...
- SSM商城开发学习
功能模块:前端:门户.商品搜索.商品展示.购物车.注册&登录 后端:商品管理.订单管理.cms 上线,bug,维护,停到上线,维护,打包,上线 某一个模块出现bug,停到这个模块 tomcat ...
- Mybateis mapper 接口 example 用法
注意:希望通过此篇文章分享 可以使大家对mapper接口以及example 用法更加深入理解 MyBatis的Mapper接口以及Example的实例函数及详解 一.mapper接口中的方法解析 ma ...
- fROM PPV report
Month search help: include rmcs0f0m. s_month for s001-spmon at selection-screen on value-request for ...
- python websocket 再线聊天室的 Demo
服务端 import tornado.web import tornado.ioloop import tornado.httpserver import tornado.options import ...
- 【java-console】如何双击运行可执行jar包及遇到依赖dll报错问题的解决办法
如何配置双击运行可执行jar包的步骤,请移步到 这里 查看具体的操作,此处不再介绍. 本文主要解决如何处理依赖dll报错的问题解决办法. 我有一个jar包可执行文件运行需要依赖第三方的dll文 ...