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调用‘用户模块’来进行授 ...
随机推荐
- ASP.NET结合Redis实现分布式缓存
最近一个项目ASP.NET+MySQL 有的网页打开初始化的查询需要10秒甚至更久,用户体验极差,而且并发量变大的时候网站容易崩溃 后来想了两种解决方案都不是太满意 1.数据库里建一张缓存表,后台作业 ...
- string转可空类型
string类型转可空类型 string.IsNullOrEmpty(str) ? (int?)null : int.Parse(str) 此处要注意将null转为可空的类型才可以,不然会报错
- php 配置xdebug
https://blog.csdn.net/Alan8865/article/details/81331252
- Windows7下安装、部署Weblogic和发布war项目
安装 1 从官方下载安装包 链接 2 下载之后,放到 Java8\jdk1.8.0\bin目录下 3 打开cmd,输入 java -jar . 4 5 6 下面是我自定义的目录, 7 8 9 10 1 ...
- laravel view not found
在windows开发的laravel项目,部署到Linux服务器找不到视图,代码格式可能是这样的 return view('news\list'); 原因是在Linux下不能识别反斜杠路径,解决办法是 ...
- 20175314 《Java程序设计》第九周学习总结
20175314 <Java程序设计>第九周学习总结 教材学习内容总结 根据课本的介绍下载了MySQL和Navicat for MySQL并成功对后者进行破解 MySQL客户端管理工具(如 ...
- python学习中遇到的错误及解决办法
1. nodename nor servname provided 原因:Python程序中有段程序调用 socket.gethostbyname(socket.gethostname()) sock ...
- L2-025 分而治之(并查集)
分而治之,各个击破是兵家常用的策略之一.在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破.为此参谋部提供了若干打击方案.本题就请你编写程序,判断每个方案的可行性 ...
- promise之我见
在我们平时的方法中有很多方法是promise封装的, 有些函数后边跟的then和catch 就是promise的方法,先看一下pormise的特点 (1)对象的状态不受外界影响.Promise对象代表 ...
- jmeter用Windows电脑分布式部署
当然,java环境.jmeter安装我这里就不说了. 使用1个controller(imac电脑),2个agent(Windows7 系统) 一.agent配置(Windows7系统) 1.电脑环境变 ...