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 ...
随机推荐
- sonarqube插件开发(三) 调试插件
环境 windows + eclipse +sonarqube server 5.6.4 准备 新建一个maven项目,其中加入了一些插件所用的jar <project xmlns=" ...
- 被C语言操作符优先级坑了
今天有一个枚举的题目的代码是这样的: 重点在于maxXor这个函数的实现,枚举两个数字,其中maxr保存了最大值的 i 异或 j , 可是这个程序执行结果大大出乎意外-_-. 然后就把 i 异或 j ...
- jquery.fn.extend与jquery.extend用法与区别
jQuery为开发插件提拱了两个方法,分别是: 代码如下 复制代码 jQuery.fn.extend(object); 和 jQuery.extend(object); jQuery.exte ...
- 使用Autolayout xib实现动态高度的TableViewCell
http://my.oschina.net/u/2360693/blog/481236?p={{totalPage}} 创建Xib文件 首先将Cell做好布局,调整到满意的位置和宽度,然后开始做Aut ...
- CSS 盒子模型 二
Sublime 快捷键: 文件保存后,输入 html:xt + tab ,补全html html:xt <!DOCTYPE html PUBLIC "-//W3C//DTD XHTM ...
- Thinkphp---自定义服务类!
考虑到有些功能是复用的,可以将一些复用的功能放到一个服务里面公用! 例如:公共模块新建一个服务类: 示例: <?php namespace Common\Service; // use Thin ...
- C 语言实现增量式PID
一直以来,pid都是控制领域的经典算法,之前尝试理解了很久,但还是一知半解,总是不得要领,昨天模仿着别人的代码写了一个增量式pid的代码. 我的理解就是pid其实就是对你设置的预定参数进行跟踪.在控制 ...
- numpy协方差矩阵numpy.cov
numpy.cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None, aweights=None)[source] Estim ...
- nginx 反向代理apache服务器 配置java与PHP共存环境
listen 80; listen 443; ssl on; ssl_certificate /passport.crt; ssl_certificate_key /passport.key; ssl ...
- TFS二次开发02——连接TFS
在上一篇<TFS二次开发01——TeamProjectsPicher>介绍了 TeamProjectsPicher 对象,使用该对象可以很简单的实现连接TFS. 但是如果我们要实现自定义 ...