mysql事务详解
事务的四大特性ACID如下:
原子性:事务中的所有操作,要么全部完成,要么不做任何操作,不能只做部分操作。如果在执行的过程中发了错误,要回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过。
事务的四大隔离级别如下:
一、读未提交。(A事务能够读取到B事务对数据的增删改操作)
该事务级别会出现脏读问题。
二、读已提交。(该事务级别不会出现脏读问题)
只要一个事务A提交了,那么事务A中对数据库表的增删改操作,都会直接反映到事务B上,因此事务B中可以查看到最新的数据。
三、可重复读。(解决了不可重复读,即其他事务的提交,在该事务中看不见,也就是select时,别的事务提交不会影响select语句的结果,但是因为别的事务已经提交了,所以在数据库中是真实存在的,只是在该事务中给屏蔽了一眼,相当于障眼法,如果此时针对别的事物的插入的数据做修改删除操作,那么会起到实际作用的,但是如果新增一条和别的事务插入的记录有违反唯一约束的,那么新增会失败。如果其他事务更新了数据,那么在本事务中不可见,)
测试如下:
1、
(1)开启两个会话A和B,并设置两个会话的数据库隔离级别为可重复读。
(2)在两个会话中分别开启两个事务A和事务B,然后分别查询同一张表user,结果如下。
(3)先在A事务中插入一条记录并提交,然后在B事务中查询。
--------------------------------------------------------------------------------------------------------------
综合上面的测试说明:
(1)如果其他事务插入了数据,那么在该事务中分几种情况:
如果直接查询,那么不会查询到其他事务提交的最新数据,即屏蔽了外界的变化,保持了数据在一个事务中任何地方查询看到的结果都是完全相同一致的;
如果在该事务中插入与其他事务提交的数据产生违反唯一性约束的话,那么该事务中导致插入失败,因为在该事务中看不见其他事务的操作,即屏蔽了外界;
但是如果更新数据时,如果更新数据的条件包含了其他事务中提交的插入数据,那么更新之后会看到这些其他事务中提交的插入数据,而且被更新了,如果更新条件不包含其他事务提交的数据,那么这些数据还是不会出现的。
如果删除数据时,如果删除数据的条件包含了其他事务中提交的数据,那么删除之后会看到这些其他事务中提交的数据也被删除了,如果删除条件不包含其他事务提交的数据,那么这些数据还是不会出现,也不会被删除。
(2)如果其他事务更新了数据,那么在该事务中分几种情况:。
如果直接查询,那么不会显示其他事务提交的最新数据,即屏蔽了外界的变化,保持了数据在一个事务中任何地方查询看到的结果都是完全相同一致的;
如果在该事务中插入与其他事务提交的删除数据有相同主键或唯一索引的话,那么该事务中插入会失败;
但是如果更新数据时,如果更新数据的条件包含了其他事务中提交的数据,那么更新之后会看到这些其他事务中提交的更新数据,而且被更新了,如果更新条件不包含其他事务提交的数据,那么这些数据还是不会出现的。
如果删除数据时,如果删除数据的条件包含了其他事务中提交的更新数据,那么删除之后会看到这些其他事务中提交的更新数据也被删除了,如果删除条件不包含其他事务提交的数据,那么这些更新数据还是不会出现,也不会被删除。
(3)如果其他事务删除了数据,那么在该事务中分几种情况:。
如果直接查询,那么仍然能够查询到其他事务提交的删除数据,即屏蔽了外界的变化,保持了数据在一个事务中任何地方查询看到的结果都是完全相同一致的;
但是如果更新数据时,如果更新数据的条件包含了其他事务中提交的删除数据,那么会出现更新异常,如果更新条件不包含其他事务提交的数删除据,那么不会出现更新异常。
如果删除数据时,如果删除数据的条件包含了其他事务中提交的删除数据,出现删除异常,如果删除条件不包含其他事务提交的删除数据,则不会出现删除异常。
(4)如果其他事务提交了的最新数据,在该事务中第一次查询,将是最新的数据,对同一张表查询将会保持相同一致的。即在事务中,任何一张表第一次读取时,那么此时的数据就是最新的,之后如果再次读取时,则不会改变,除非上述情况。(首次读取=最新数据)。
举例说明:执行时间如下顺序:
(1)事务A开启,并执行第一次查询操作。
(2)事务B更新数据并提交。
(3)事务A更新B更新过的数据,结果发现不是104,而是140,这就是幻读。明明更新前一刻查询是4,再更新一次,结果却是用到了B事务提交过来的数据。
(4)因此需要特别注意这类幻读造成的危害。后果很严重。那么如何避免这类严重问题?
(a)添加读锁。select * from t1 where id=5 lock in share mode;如果在事务A中对指定的记录行添加读锁,那么其他事务最多也只能给这些记录行添加读锁,其他添加事务给这些记录添加不了写锁了,如果其他事务添加写锁,那么会被阻塞,直到其他所有读锁都释放了。因此在事务A结束之前,这些记录行一定不会被其他事务修改/删除/插入(注意:此处插入是指插入与这些记录行有相同的唯一索引或主键的数据),只有当这些记录行的其他读锁和写锁都释放了,那么才能够被修改/删除/插入相同。但是如果同时想在事务A中修改加了读锁的这些记录行时,只有当这些记录行还没有被其他事务加读锁,那么这些被自己加了读锁的记录行就可以修改;如果有其他事务也给这些记录行添加了读锁,那么修改操作将会被阻塞,直到其他事务的读锁都释放了才能被修改成功。因此,给指定记录行添加读锁,只是为了在本事务执行期间(事务还没有结束)不想让这些记录行的数据被修改/删除/插入相同,同时本事务也不想修改/删除/插入相同这些记录行。也就是冻结数据,不让任何事务篡改已经存在的数据。切记自己给这些记录行添加了读锁,同时自己又要更新/删除/插入相同这些记录行,这会带来严重的性能下降和不确定性增加,效率也会低下。
(b)添加写锁。select * from t1 where id=5 for update;如果事务A给指定的记录行添加了写锁,那么其他事务进行select读取这些记录行是一点都没有问题的。如果其他事务对这些记录行尝试添加读锁或者写锁时,都会被阻塞掉,等待时间到了之后而且事务A还没有结束时就会返回空的数据行,如果等待时间还没有到事务A却结束了,那么其他事务可以获取到指定的记录行的读锁或写锁。如果事务A还没有结束,那么其他事务只能读取到这些记录行,但是不能更新/删除/插入相同这些记录行,如果其他事务尝试更新/删除/插入相同这些记录行就会被阻塞,直到事务A结束或等待超时,如果事务A提前结束,那么更新/删除会成功,等待超时肯定是失败了。这些记录行的写锁,可以在本事务中来修改/删除这些记录行。因此,添加指定记录行的写锁,其他事务可以select简单查询,禁止了其他事务写锁读和读锁读,也禁止了其他事务更新/删除这些记录行,本事务却可以任意地更新/删除这些记录行。
(5)简单可重复读现场举例。
(a)先查询数据再开启事务A。
(b)开启事务B,然后插入一条记录(6,6)并提交成功。
(c)在事务A中第一次查询数据。获取到了最新的数据。
(d)再开启另外一个事务C,并插入一条记录(7,7),并提交成功。
(e)再在事务A中进行第二次简单select查询。结果和第一次查询的结果相同。
(6)Innodb存储引擎的mvcc并发控制。
四、可串行化。
mysql事务详解的更多相关文章
- 数据库 Mysql事务详解
Mysql事务 mysql的事务默认是自动提交的,也就是你提交一个query,他就直接执行!我们可以通过 禁止自动提交 开启自动提交 //mysql事务 #include <stdio.h> ...
- mysql由浅入深探究(四)----mysql事务详解
什么是事务: 通俗的解释就是对数据库进行的一组完整的操作,这组完整的操作中包含一个或多个操作.解释的太low了,来点官方的:事务就是DBMS中执行的一个完整的逻辑单元,这个逻辑单元中包含一个或者多个操 ...
- PHP mysql与mysqli事务详解
官方对PHP连接到MySQL数据库服务器的三种主要的API简介如下: http://php.net/manual/zh/mysqli.overview.php PHP mysql与mysqli事务详解 ...
- MySQL 数据类型 详解
MySQL 数据类型 详解 MySQL 的数值数据类型可以大致划分为两个类别,一个是整数,另一个是浮点数或小数.许多不同的子类型对这些类别中的每一个都是可用的,每个子类型支持不同大小的数据,并且 My ...
- MySQL配置文件详解
MYSQL 配置文件详解 “全局缓存”.“线程缓存”,全局缓存是所有线程共享,线程缓存是每个线程连接上数据时创建一个线程(如果没有设置线程池),假如有200连接.那就是200个线程,如果参数设定值是1 ...
- spring事务详解(五)总结提高
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.概念 ...
- spring事务详解(四)测试验证
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
- spring事务详解(一)初探事务
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 引子 很多 ...
- MySQL状态变量详解
MySQL状态变量详解 mysql的状态变量(status variables)记录的mysql服务器的运行状态信息.查看语法如下: SHOW [GLOBAL | SESSION] STATUS; S ...
随机推荐
- sencha touch 类的使用
sencha touch 有一套自己的类机制,可以以面向对象的方式去写代码,封装业务逻辑,sencha touch 的组件.插件.api等都建立在这一套类机制的上面 在实际开发中,我们需要遵循这一套机 ...
- react封装简单的浏览器顶部加载进度条全局组件
在项目中经常会有在请求前后加loading或者加加载进度条,一般这些组件都会抽离出来作为全局组件 进度条的插件貌似都不是很符合自己项目中的需求,于是.. 参考nprogress样式,自己在项目中封装组 ...
- Python面向对象之字段
类成员: 字段,方法,属性 属性是在一个函数方法前面加一个装饰器,伪造成为一个字段,调用的时候不需要加括号() 目的是把一个方法伪造成为一个字段,属性也是方法的一种,对这个方法进行改造就可以以 字段的 ...
- SPOJ IM - Intergalactic Map - [拆点最大流]
题目链接:http://www.spoj.com/problems/IM/en/ Time limit:491 ms Memory limit:1572864 kB Code length Limit ...
- ip相关问题解答
用路由器上网时电脑的设置: ===================== 路由器如何设置另外讨论,现只讲电脑的设置.在Windows XP下: 1.确定桌面上有没有“网上邻居”图标,如果没有,在桌面空白 ...
- nginx map使用方法
map指令使用ngx_http_map_module模块提供的.默认情况下,nginx有加载这个模块,除非人为的 --without-http_map_module.ngx_http_map_modu ...
- PXE配置手记(Linux)
服务器端:RHEL5(静态IP 192.168.1.101) 源Gentoo系统:服务器上的Gentoo系统就来自于它,编译内核也是在这台机器上执行的 无盘客户端:网卡是 AMD PCnet32 支持 ...
- count(*) count(1) count(column)区别
count(*) 和count(1)的效果是一样的.在某些情况下效率不一样.也会统计包含null的记录. count(column)会返回当前字段不为null的记录数.
- 【转】基于jquery,bootstrap数据验证插件bootstrapValidator 教程
bootstrap:能够增加兼容性的强大框架. 因为项目需要数据验证,看bootstrapValidator 还不错,就上手一直,完美兼容,话不多说. 需要引用css: bootstrap.min.c ...
- Vagrant入门一(转)
原文: https://github.com/astaxie/Go-best-practice/blob/master/ebook/zh/01.2.md 1.2 Vagrant安装配置 实际上Vagr ...