出自:https://blog.csdn.net/u014439239/article/details/78086729

数据库事务有不同的隔离级别,不同的隔离级别对锁的使用是不同的,锁的应用最终导致不同事务的隔离级别。

隔离性分为四个级别:

1读未提交:(Read Uncommitted)

2读已提交(Read Committed) 大多数数据库默认的隔离级别

3可重复读(Repeatable-Read) mysql数据库所默认的级别

4序列化(serializable)

四个级别的具体实现和不同的请下面细读:

首先程序是可以并发执行的,同样,在MySQL中,一个表可以由两个或多个进程同时来读写数据,这是没有问题的。

比如,此时有两个进程来读数据,这也没什么问题,允许。但是如果一个进程在读某一行的数据的过程中,另一个在进程又往这一行里面写数据(改、删),那结果会是如何?同样,如果两个进程都同时对某一行数据进行更改,以谁的更改为准?那结果又会怎样,不敢想象,是不是数据就被破坏掉了。所以此时是冲突的。

既然会冲突就要想办法解决,靠谁来解决,这时候就是靠锁机制来维护了。怎么使用锁来使他们不冲突?

在事务开始的时候可以给要准备写操作的这一行数据加一个排它锁,如果是读操作,就给该行数据一个读锁。这样之后,在修改该行数据的时候,不让其他进程对该行数据有任何操作。而读该行数据的时候,其他进程不能更改,但可以读。读或写完成时,释放锁,最后commit提交。这时候读写就分离开了,写和写也就分离开了。

注意:此时加锁和释放锁的过程由mysql数据库自身来维护,不需要我们人为干涉。mysql开发者给这个解决冲突的方案起了一个名字叫做:读未提交:(Read Uncommitted)。这也就是事务的第一个隔离性。

但是这个程度的隔离性仅仅是不够的。看下面的测试结果:

1)A修改事务级别为:未提交读。并开始事务,对user表做一次查询

2)B事务更新一条记录

3)此时B事务还未提交,A在事务内做一次查询,发现查询结果已经改变

4)B进行事务回滚

5)A再做一次查询,查询结果又变回去了

由试验得知:在一个进程的事务当中,我更改了其中的一行数据,但是我修改完之后就释放了锁,这时候另一个进程读取了该数据,此时先前的事务是还未提交的,直到我回滚了数据,另一个进程读的数据就变成了无用的或者是错误的数据。我们通常把这种数据叫做脏数据,这种情况读出来的数据叫做賍读。

怎么办?依然是靠锁机制。无非是锁的位置不同而已,之前是只要操作完该数据就立马释放掉锁,现在是把释放锁的位置调整到事务提交之后,此时在事务提交前,其他进程是无法对该行数据进行读取的,包括任何操作。那么数据库为此种状态的数据库操作规则又给了一个名字叫做:读已提交(Read Committed),或者也可以叫不可重复读。这也就是事务的第二个隔离性。

在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……

继续看下面的测试结果:

1)把隔离性调为READ-COMMITTED(读取提交内容)设置A的事务隔离级别,并进入事务做一次查询

2)B开始事务,并对记录进行修改

3)A再对user表进行查询,发现记录没有受到影响

4)B提交事务

5)A再对user表查询,发现记录被修改

试验进行到这里,你会发现,在同一个事务中如果两次读取相同的数据时,最后的结果却不一致。这里我们把这种现象称为:不可重复读。因为在第一个事务读取了数据之后,此时另一个事务把该数据给修改了,这时候事务提交,那么另一个事务在第二次读取的时候,结果就不一样,一个修改前的,一个是修改后的。

但是细心的你会发现,既然你说此种隔离性是在事务提交后才释放锁,那么在试验过程中,在该数据未提交前,另一个事务为什么也是仍然可以读取的呀。是我说错了吗?不是的,在这里mysql使用了一个并发版本控制机制,他们把它叫做MVCC,通俗的也就是说:mysql为了提高系统的并发量,在事务未提交前,虽然事务内操作的数据是锁定状态,但是另一个事务仍然可以读取,大多数数据库默认的就是这个级别的隔离性。但mysql不是。

而且不只是在更新数据时出现这个问题,在插入数据时仍然会造成类似的这样一种现象:mysql虽然锁住了正在操作的数据行,但它仍然不会阻止另一个事务往表插入新行新的数据。比如:一个事务读取或更新了表里的所有行,接者又有另一个事务往该表里插入一个新行,在事务提交后。原来读取或更改过数据的事务又第二次读取了相同的数据,这时候这个事务中两次读取的结果集行数就不一样。原来更新了所有行,而现在读出来发现竟然还有一行没有更新。这就是所谓的幻读。

为了防止同事务中两次读取数据不一致,(包括不可重读和幻读),接下来该如何继续做呢?!

mysql依然采取的是MVCC并发版本控制来解决这个问题。具体是:如果事务中存在多次读取同样的数据,MySQL第一次读的时候仍然会保持选择读最新提交事务的数据,当第一次之后,之后再读时,mysql会取第一次读取的数据作为结果。这样就保证了同一个事务多次读取数据时数据的一致性。这时候,mysql把这种解决方案叫做:可重复度(Repeatable-Read),也就是上述所写的第三个隔离性,也是mysql默认的隔离级别。

注意:幻读和不可重复读(Read Committed)都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

说到这里,真的就完事了吗?到这里其实mysql并未完全解决数据的一致性问题。只是在读取上做了手脚,解决了传统意义上的幻读和不可重复读。

例子:1 A事务开启,B事务开启。

2 B事务往表里面插入了一条数据,但还并未提交。

3 A事务开始查询了,并没有发现B事务这次插入的数据。然后此时B事务提交了数据。

4 于是乎,A事务就以为没有这条数据,就开始添加这条数据,但是却发现,发生了数据 重复冲突。

最后这个时候,该我们的最后一种隔离级别也是最高的隔离级:别序列化(serializable)登场了。

该隔离级别会自动在锁住你要操作的整个表的数据,如果另一个进程事务想要操作表里的任何数据就需要等待获得锁的进程操作完成释放锁。可避免脏读、不可重复读、幻读的发生。当然性能会下降很多,会导致很多的进程相互排队竞争锁。

后记:以上所说的四种隔离性的锁机制应用是数据库自动完成的,不需要人为干预。隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效。

mysql数据库事务类型的更多相关文章

  1. MySQL数据库事务剖析

    MySQL数据库事务剖析 事务就是一组原子性的SQL查询,是一个独立的执行单元.事务内的语句,要么全部执行成功,要么全部执行失败. 1.事务的标准特征 一个运行良好的事务处理系统,必须具备原子性.一致 ...

  2. mysql数据库事务详细剖析

    在写之前交代一下背景吧! 做开发也好久了,没怎么整理过知识,现在剖析一下自己对数据库事务的认识,以前用sqlserver,现在转java后又用mysql.oracle.我这块就主要解释一下mysql数 ...

  3. Mysql数据库事务隔离级别

    事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...

  4. MySql数据库事务正常提交,回滚失败

    问题:在初次练习Mysql数据库事务时,事务正常提交,但是在遇到异常应当回滚时,回滚失败. 代码如下: //2.更新操作. public void update(Connection conn, St ...

  5. MYSQL数据库索引类型及使用

    MYSQL数据库索引类型包括普通索引,唯一索引,主键索引与组合索引,这里对这些索引的做一些简单描述: (1)普通索引 这是最基本的MySQL数据库索引,它没有任何限制.它有以下几种创建方式: 创建索引 ...

  6. Mysql数据库事务的隔离级别和锁的实现原理分析

    Mysql数据库事务的隔离级别和锁的实现原理分析 找到大神了:http://blog.csdn.net/tangkund3218/article/details/51753243 InnoDB使用MV ...

  7. MYSQL数据库约束类型

    07.14自我总结 MYSQL数据库约束类型 一.主键约束(primary key) 主键约束要求主键列的数据唯一,并且不能为空.主键分为两种类型:单字段主键和多字段联合主键. 1.单字段主键 写法 ...

  8. Mysql数据库日志类型查询与配置详解

    在mysql中日志分为很多种,下面小编来给大家介绍Mysql数据库日志类型查询与使用,希望对各位同学会有所帮助 mysql常见的日志类型有五种:错误日志.二进制日志.查询日志.慢查日志和中继日志. 一 ...

  9. 理解MySQL数据库事务

    1. 什么是事务处理? 事务处理是一种机制,它是用来管理必须成批执行的mysql操作.来保证数据库不完整的操作结果. 2. 为什么要使用事务处理? 在使用mysql操作数据的过程中,如果只是简单的中小 ...

随机推荐

  1. 火鸡堂 对 基于云的胜利冲锋队 为了交项目干杯 的 Beta 产品测试报告

    基于云的胜利冲锋队 第一次上手 第一次上手体验感觉如何?能否正常运行? 不错,学生端和老师端各功能很清晰,大部分功能正常运行,但添加班级之类的部分功能页面暂时无响应 看到千帆竞发图泪流满面,图表中有各 ...

  2. Flutter 数据存储之 shared_preferences

    资源名称 网址 github https://github.com/flutter/plugins/tree/master/packages/shared_preferences Flutter 数据 ...

  3. 没有内置小鹤双拼的rime输入法就是差劲

    没有内置小鹤双拼的rime输入法就是差劲,还特立独行,搞什么繁体~ 没有内置小鹤双拼的rime输入法就是差劲,还特立独行,搞什么繁体~ 没有内置小鹤双拼的rime输入法就是差劲,还特立独行,搞什么繁体 ...

  4. keil中error: #70: incomplete type is not allowed—解决方法

    今天在写程序的时候,想使用sizeof求数组的大小,数组中其他c文件定义,在头文件使用extern uint8_t buff_value[]; 声明 但是keil编译报错,网上查了,发现,需要写成ex ...

  5. js版本规范的表示:ES6 == ES 6 == ECMAScript 6 == ECMA-262 6

    Ecma 国际大会宣布正式批准ECMA-262第 6 版,亦即 ECMAScript 2015(曾用名:ECMAScript 6.ES6)的语言规范. 关系 ECMA-262 == ECMAScrip ...

  6. codeforces1267G

    考虑我们在某个时刻,剩下的数有 $ i $ 个,这些数的和为 $ j $,那么我们期望要抽 $ n \over i $ 次才能取到一个新的物品,这个物品的期望权值为 $ j \over i $,我们花 ...

  7. log4j2 配置文件解读

    1.日志相关介绍 日志接口(slf4j):slf4j是对所有日志框架制定的一种规范.标准.接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用,比如log4j.l ...

  8. [Inside HotSpot] Serial垃圾回收器 (一) Full GC

    Serial垃圾回收器Full GC Serial垃圾回收器的Full GC使用标记-压缩(Mark-Compact)进行垃圾回收,该算法基于Donald E. Knuth提出的Lisp2算法,它会把 ...

  9. 学习:窗口创建以及消息处理basic.c

    WNDCLASS结构: Windows 的窗口总是基于窗口类来创建的,窗口类同时确定了处理窗口消息的窗口过程(回调函数). 在创建应用程序窗口之前,必须调用 RegisterClass 函数来注册窗口 ...

  10. iOS 逆向工程(工具介绍)- 学习整理(转)

    一.class-dump 简介:顾名思义,就是用来导出目标对象的class信息的工具,私有方法声明也能导出来. 原理:利用 Objective-C语言的 runtime 特性,将存 在Mach-O 文 ...