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 压缩js,css遇到的问题
在使用工具压缩css和jss时,我遇到了以下问题 1. showBtn: { tap: function (t, value) { this.redirectTo(t.config.goto); } ...
- [转]13 Hours: The Secret Soldiers of Benghazi
转:http://www.imfdb.org/wiki/13_Hours:_The_Secret_Soldiers_of_Benghazi The following weapons were use ...
- 如何在Computer下添加System Folder(续)
之前的一篇博客如何在Computer下添加System Folder里提到需要每次都使用一个新的guid,否则再次在"HKEY_LOCAL_MACHINE\SOFTWARE\Microsof ...
- window7下 cocos2dx android交叉编译环境部署小结
上周被android交叉编译搞惨了,还好最后弄好了,写个小结以后备用吧. 步骤,1.下载cygwin的devel和shells模块 2. 2.设置环境变量 a.设置NDK_ROOT b.设置Path ...
- centos7下安装nmon后,无法运行,提示 cannot execute binary file或/lib64/ld64.so.1不存在
在centos 7.1上安装nmon后,从管网(http://nmon.sourceforge.net/pmwiki.php?n=Site.Download)下载tar包解压后,两台机器一台提示 ca ...
- ThreadLocal Java并发
ThreadLocal 文章来源:http://con.zhangjikai.com/ThreadLocal.html ThreadLocal 主要用来提供线程局部变量,也就是变量只对当前线程可见. ...
- CentOS 6.8下Apache绑定多个域名的方法
如何通过设置Apache的http.conf文件,进行多个域名的绑定(假设我们要绑定的域名是discuz11.com和discuz22.com,独立IP为25.25.25.25). 域名/IP地址 域 ...
- POJ 1269 - Intersecting Lines - [平面几何模板题]
题目链接:http://poj.org/problem?id=1269 Time Limit: 1000MS Memory Limit: 10000K Description We all know ...
- Oracle安装部署之rhel 5.8下静默安装oracle11gr2
1.图形界面下录制脚本如下: #-------------------------------------------------------------------------------# Do ...
- The History of Operating Systems
COMPPUTER SCIENCE AN OVERVIEW 11th Edition job 作业 batch processing 批处理 queue 队列 job queue 作业队列 first ...