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调用‘用户模块’来进行授 ...
随机推荐
- Could not HEAD 'https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.2.0/gradle-3.2.0.pom'.
- 29. Divide Two Integers (JAVA)
Given two integers dividend and divisor, divide two integers without using multiplication, division ...
- 原型设计工具—Axure
作为软件设计的一员,需要在软件开发初期确保软件的具体内容,防止后期大幅度的修改. 在这样的情况下,原型设计软件就起到了关键的作用. 摘要: 原型设计为什么这么重要呢? 因为它帮助我们搭建了低保真或高保 ...
- 10.17 elemen.js
今天终于把element.js的官方文档看完了,主要是基础组件的用法,看的时候有种之前学bootstrap的感觉,似曾相识. 虽然它是基于VUE的,但是展示给我们的代码已经精简到不用会VUE也能看懂了 ...
- Vue --1
1.2 vue.js库的基本使用 在github下载:https://github.com/vuejs/vue/releases 在官网下载地址: https://cn.vuejs.org/v2/gu ...
- ABAP开发规范
一.数据库操作 1.禁止修改系统标准表. 2.如果使用到FOR ALL ENTRIES IN语句取数,一定要校验关联内表非空性. 3.禁止一条SELECT关联的表超过5张,需要多表取值的时候建议分开取 ...
- 避免切换横竖屏Fragment的重复加载导致UI混乱
当我们切换横竖屏时 Activity的生命周期就会重走一遍,自然 其中的Fragment的生命周期也就重新走了一遍,实践证明 当熄屏 再开屏时 Fragment的生命周期也会重走一遍 解决方案: an ...
- 使用idea的springboot项目出现org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
参考: https://www.cnblogs.com/lfm601508022/p/InvalidBoundStatement.html https://blog.csdn.net/xsggsx/a ...
- 7A - Max Sum
Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. F ...
- Python实现对CSV文件的读写功能
我们要处理csv文件,首先要的导入csv模块 import csv #读取csv文件def readCsv(path): #传入变量csv文件的路径 list=[] #定义一个空列表 with ope ...