首先说说什么是ACID:

它们分别是Atomicity(原子性),Consistency(一致性),Isolation(隔离性),Transaction(持久性)

原子性:

意为单个事务里的多个操作要么一起成功,要么一起失败.比如现在有三个插入操作,那么前两个成功,第三个失败了,此时,前两个也不再算数,数据库会回滚到事务开始之前的状态.

innodb靠着undo缓冲区实现,也就是当事务开始的时候,首先将会受到影响的行当前的状态保存到undo缓冲区中,一旦失败,则回滚.

一致性:

单个事务对数据库的影响必须要保证是从一个状态到另一个状态的,这个怎么理解呢?将它理解为对原子性的补充就行了,也就是说,你一个事务里三个操作,如果其中一个失败了,其它的也不能对我的数据库造成影响,必须要三个一起成功才行.

这个的实现就是原子性的实现

隔离性:

这个是靠数据库锁实现的,数据库锁实在太繁杂,我这里就说说怎么mysql是怎么保证了在可重复读的情况下就避免了不可重复读和幻读吧.

首先,mysql的读操作在innodb下的读提交和可重复读的情况下都是使用了Mvcc,这个Mvcc将它理解为一个快照就可以了,而读已提交在一个事务里多次读的情况下,每次读都会读最新的已提交的数据.由此也就出现了幻读和不可重复读

比如A线程在一个事务里连续两次select

在第一次select后,B线程插入了一条数据,并且提交了事务.

此时A线程因为每次都是读最新的已提交的数据自然就读到了B线程插入的数据.

而在可重复读的情况下呢?

首先可重复读的情况下读Mvcc每次都是读第一次select的数据,由此就避免了可重复读和幻读的产生,因为B线程插入的数据对线程A的事务没有任何影响,但这样就代表没问题了吗?

假设这样一个场景,线程A要拿到当前最大的ID然后自增之后插入

假设现在数据库最大ID为10

线程A查询后,自增为11,并准备插入

但此时线程B插入一条数据,并且ID为11.

此时线程A插入,然后报错.

由此可见,此时还是会有问题.

那么怎么解决呢?很简单,使用select max(id) from table for update

因为在可重复读的情况下,使用排它锁,会默认升级为间隙排他锁,什么叫间隙排他锁呢?就是会锁离你最近的两个行数据,并且还有他们之间,不让别人进行增删改查操作,如果没有则取无限集.

那么此时,10右区间无限集就被锁起来了,线程B自然没法查询数据(当然也有可能是A,看谁先拿到锁).此时线程A就插入成功,然后B开始查询,之后插入(这里说下为什么是排他锁而不是共享锁呢?因为线程A和线程B在并发的情况下查了max(id)后,他们拿到的都是相同的数据,也就会在插入的时候报错,所以此时直接让他们其中一个堵在select那里,这样另一方拿到数据后,就会更新id,另一方也能拿到最新值了)

持久性:

  事务提交后,事务里的数据必须要进行刷盘,也就是强同步

  这里要插一句的是,当事务提交后,数据本身不会马上刷盘,而是由一个redo缓冲区保存了插入日志,进行刷盘,为什么要这样做呢?因为redo是日志数据,所以可以顺序写,而数据刷盘则是要找到文件里数据所在的索引,也就是随机写,而随机写比顺序写慢很多,毕竟多了硬盘寻址的操作.

纯干货,Mysql innodb的ACID特性是怎么实现的?以及高并发情况下会出现的问题的更多相关文章

  1. Mysql高并发情况下的解决方案(转)

    查询了下Mysql 关于高并发的处理的资料,在这记录一下. 高并发大多的瓶颈在后台数据逻辑处理,在存储,mysql的正常的优化方案如下: 1.代码中sql语句优化 2.数据库字段优化,索引优化 3.加 ...

  2. Mysql在高并发情况下,防止库存超卖而小于0的解决方案

    背景: 本人上次做申领campaign的PHP后台时,因为项目上线后某些时段同时申领的人过多,导致一些专柜的存货为负数(<0),还好并发量不是特别大,只存在于小部分专柜而且一般都是-1的状况,没 ...

  3. 深入学习MySQL事务:ACID特性的实现原理

    事务是MySQL等关系型数据库区别于NoSQL的重要方面,是保证数据一致性的重要手段.本文将首先介绍MySQL事务相关的基础概念,然后介绍事务的ACID特性,并分析其实现原理. MySQL博大精深,文 ...

  4. MySQL事务及ACID特性

    一.事物 1.定义:事务是访问和更新数据库的程序执行单元,事务中包含一条或者多条SQL语句,这些语句要么全部执行成功,要么都不执行. 在MySQL中,事务支持是在引擎层实现的,MySQL是一个支持多引 ...

  5. 一文说尽MySQL事务及ACID特性的实现原理

    MySQL 事务基础概念 事务(Transaction)是访问和更新数据库的程序执行单元:事务中可能包含一个或多个 sql 语句,这些语句要么都执行,要么都不执行.作为一个关系型数据库,MySQL 支 ...

  6. MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能

    MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能 Clicks: Date: -- :: Power By 李轩Lane TagMysql计数器高性能 现在有很多的项目,对计数器的实现 ...

  7. 【转】记录PHP、MySQL在高并发场景下产生的一次事故

    看了一篇网友日志,感觉工作中值得借鉴,原文如下: 事故描述 在一次项目中,上线了一新功能之后,陆陆续续的有客服向我们反应,有用户的个别道具数量高达42亿,但是当时一直没有到证据表示这是,确实存在,并且 ...

  8. 搞懂MySQL InnoDB事务ACID实现原理

    前言 说到数据库事务,想到的就是要么都做修改,要么都不做.或者是ACID的概念.其实事务的本质就是锁和并发和重做日志的结合体.那么,这一篇主要讲一下InnoDB中的事务到底是如何实现ACID的. 原子 ...

  9. [纯干货] MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

随机推荐

  1. UVA 1661 Equation (后缀表达式,表达式树,模拟,实现)

    题意:给出一个后缀表达式f(x),最多出现一次x,解方程f(x) = 0. 读取的时候用一个栈保存之前的结点,可以得到一颗二叉树,标记出现'X'的路径,先把没有出现'X'的子树算完,由于读取建树的时候 ...

  2. 树形dp——覆盖所有边的最少费用(Protecting Zonk)

    一.问题描述 有一个n(n<=10000)个节点的无根树.有两种装置A,B,每种都有无限多个. 1.在某个节点X使用A装置需要C1(C1<=1000)的花费,并且此时与节点X相连的边都被覆 ...

  3. 并查集+思维——Destroying Array

    一.题目描述(题目链接) 给定一个序列,按指定的顺序逐一删掉,求连续子序列和的最大值.例如序列1 3 2 5,按3 4 1 2的顺序删除,即依次删除第3个.第4个.第1个.第2个,答案为5 4 3 0 ...

  4. OpenCV2:总结篇 core模块

    一.cv::Mat 1.作用 cv::Mat表示图像类,用来操作图像和矩阵,它包含很多属性和方法 2.构造方法 cv::Mat image;  //cv::Mat image()      无参数构造 ...

  5. VS2019 KEY

    VS2019正式版 密钥 Visual Studio 2019 破解 激活码 Key   Visual Studio 2019 Enterprise 企业版(亲测可用):BF8Y8-GN2QH-T84 ...

  6. Sql Server 自动备份

    1)启动代理服务 服务->Sql server 代理启动 2)设置维护计划 维护计划->设置维护计划向导->修改名称及说明 3)更改计划 4)选择维护任务 5)顺序调整不做解释 6) ...

  7. flask模板语言

    由于Django的模板引擎和Flask中的Jinja2模板引擎有很多一样的地方,所以我将一样的地方总结到了独立的文章中 https://www.cnblogs.com/kuxingseng95/art ...

  8. jquery html5 实现placeholder 兼容password ie6

    <style type="text/css"> /* 设置提示文字颜色 */ ::-webkit-input-placeholder { color: #838383; ...

  9. django-ckeditor添加代码功能(codesnippet)

    最近做了一个博客,使用python3+django2.1开发的,后台编辑器和前端显示用的Django-ckeditor富文本编辑器,由于发现没有代码块功能,写上去的代码在前端展示有点乱,于是一顿问度娘 ...

  10. python 多线程 压测 mysql

    #!/usr/bin/env python # encoding: utf-8 #@author: 东哥加油 #@file: sthread.py #@time: 2018/9/17 17:07 im ...