mysql事务详解

摘要:
事务的四个隔离级别如下:1.读取未提交。删除数据时,如果删除数据的条件包括其他事务提交的删除数据,则会发生删除异常。如果删除条件不包括其他事务提交的删除数据,则不会发生删除异常。事务B更新数据并提交。这就是冻结数据,防止任何事务篡改现有数据。选择*fromt1,其中id=5用于更新;如果事务A向指定的记录行添加写锁,则其他事务选择和读取这些记录行没有问题。

事务的四大特性ACID如下:

      原子性:事务中的所有操作,要么全部完成,要么不做任何操作,不能只做部分操作。如果在执行的过程中发了错误,要回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过。

mysql事务详解第1张

mysql事务详解第2张

 

 

 

 

事务的四大隔离级别如下:

一、读未提交。(A事务能够读取到B事务对数据的增删改操作)

  该事务级别会出现脏读问题。

 

二、读已提交。(该事务级别不会出现脏读问题)

   只要一个事务A提交了,那么事务A中对数据库表的增删改操作,都会直接反映到事务B上,因此事务B中可以查看到最新的数据。

三、可重复读。(解决了不可重复读,即其他事务的提交,在该事务中看不见,也就是select时,别的事务提交不会影响select语句的结果,但是因为别的事务已经提交了,所以在数据库中是真实存在的,只是在该事务中给屏蔽了一眼,相当于障眼法,如果此时针对别的事物的插入的数据做修改删除操作,那么会起到实际作用的,但是如果新增一条和别的事务插入的记录有违反唯一约束的,那么新增会失败。如果其他事务更新了数据,那么在本事务中不可见,)

测试如下:

       1、

       (1)开启两个会话A和B,并设置两个会话的数据库隔离级别为可重复读。

mysql事务详解第3张

mysql事务详解第4张

 

 

     (2)在两个会话中分别开启两个事务A和事务B,然后分别查询同一张表user,结果如下。

mysql事务详解第5张

mysql事务详解第6张

 

 

    (3)先在A事务中插入一条记录并提交,然后在B事务中查询。

mysql事务详解第7张

--------------------------------------------------------------------------------------------------------------

mysql事务详解第8张

mysql事务详解第9张

mysql事务详解第10张

 综合上面的测试说明:

      (1)如果其他事务插入了数据,那么在该事务中分几种情况:

          如果直接查询,那么不会查询到其他事务提交的最新数据,即屏蔽了外界的变化,保持了数据在一个事务中任何地方查询看到的结果都是完全相同一致的;

          如果在该事务中插入与其他事务提交的数据产生违反唯一性约束的话,那么该事务中导致插入失败,因为在该事务中看不见其他事务的操作,即屏蔽了外界;

          但是如果更新数据时,如果更新数据的条件包含了其他事务中提交的插入数据,那么更新之后会看到这些其他事务中提交的插入数据,而且被更新了,如果更新条件不包含其他事务提交的数据,那么这些数据还是不会出现的。

         如果删除数据时,如果删除数据的条件包含了其他事务中提交的数据,那么删除之后会看到这些其他事务中提交的数据也被删除了,如果删除条件不包含其他事务提交的数据,那么这些数据还是不会出现,也不会被删除。

      (2)如果其他事务更新了数据,那么在该事务中分几种情况:。

 

          如果直接查询,那么不会显示其他事务提交的最新数据,即屏蔽了外界的变化,保持了数据在一个事务中任何地方查询看到的结果都是完全相同一致的;

          如果在该事务中插入与其他事务提交的删除数据有相同主键或唯一索引的话,那么该事务中插入会失败;

 

          但是如果更新数据时,如果更新数据的条件包含了其他事务中提交的数据,那么更新之后会看到这些其他事务中提交的更新数据,而且被更新了,如果更新条件不包含其他事务提交的数据,那么这些数据还是不会出现的。

 

         如果删除数据时,如果删除数据的条件包含了其他事务中提交的更新数据,那么删除之后会看到这些其他事务中提交的更新数据也被删除了,如果删除条件不包含其他事务提交的数据,那么这些更新数据还是不会出现,也不会被删除。

      (3)如果其他事务删除了数据,那么在该事务中分几种情况:。

          如果直接查询,那么仍然能够查询到其他事务提交的删除数据,即屏蔽了外界的变化,保持了数据在一个事务中任何地方查询看到的结果都是完全相同一致的;

          但是如果更新数据时,如果更新数据的条件包含了其他事务中提交的删除数据,那么会出现更新异常,如果更新条件不包含其他事务提交的数删除据,那么不会出现更新异常。

          如果删除数据时,如果删除数据的条件包含了其他事务中提交的删除数据,出现删除异常,如果删除条件不包含其他事务提交的删除数据,则不会出现删除异常。

      (4)如果其他事务提交了的最新数据,在该事务中第一次查询,将是最新的数据,对同一张表查询将会保持相同一致的。即在事务中,任何一张表第一次读取时,那么此时的数据就是最新的,之后如果再次读取时,则不会改变,除非上述情况。(首次读取=最新数据)。

 

 

 举例说明:执行时间如下顺序:

   (1)事务A开启,并执行第一次查询操作。

mysql事务详解第11张

 

   (2)事务B更新数据并提交。

mysql事务详解第12张

 

   (3)事务A更新B更新过的数据,结果发现不是104,而是140,这就是幻读。明明更新前一刻查询是4,再更新一次,结果却是用到了B事务提交过来的数据。

mysql事务详解第13张

 

   (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。

mysql事务详解第14张

 

      (b)开启事务B,然后插入一条记录(6,6)并提交成功。

mysql事务详解第15张

 

      (c)在事务A中第一次查询数据。获取到了最新的数据。

 mysql事务详解第16张

 

      (d)再开启另外一个事务C,并插入一条记录(7,7),并提交成功。

mysql事务详解第17张

 

      (e)再在事务A中进行第二次简单select查询。结果和第一次查询的结果相同。

mysql事务详解第18张

 

   (6)Innodb存储引擎的mvcc并发控制。

mysql事务详解第19张

 mysql事务详解第20张

 

mysql事务详解第21张

 mysql事务详解第22张

 

四、可串行化。

免责声明:文章转载自《mysql事务详解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇神经机器翻译(NMT)相关资料整理python 通过pip freeze、dowload打离线包及自动安装【适用于保密的离线环境】下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mysql hang and srv_error_monitor_thread using 100% cpu(已解决)

昨天晚上,运维过来说有台生产服务器的mysql cpu一直100%,新的客户端登录不了,但是已经在运行的应用都正常可用。 登录服务器后,top -H看了下,其中一个线程的cpu 一直100%,其他的几乎都空闲。 MySQL thread id 14560536, OS thread handle 0x7f1255ef1700, query id 31889...

MySQL-快速入门(8)存储过程、存储函数

1、存储过程 1》创建存储过程:create procedure create procedure sp_name ([in | out | inout]param_name type) [characteristics ...] routine_body characteristics指定存储过程的特性: 1>language sql:说明rou...

Mac安装MySQL

Mac安装MySQL没有Win下那么智能(无脑), 还须要一些配置步骤。 网上教程不够具体, 找了几篇综合起来才安装好, 因此留个印记, 帮其它人降低点时间损耗: 1. 去官网下一个mysql-*.*.*-osx10.9-x86_64.dmg, 注意选择对应CPU位数的 2. 安装完后, 改密码 :/usr/local/mysql/bin/mysql...

【Centos7裁剪】

#!/bin/sh rootdir=`pwd` rm -rf ${rootdir}/centos* KERNEL_DIR=${rootdir}/kernel ROOTFS_DIR=${rootdir}/rootfs if [ -d ${KERNEL_DIR} ]; then echo "remove kernel dir" rm -rf...

php实现SESSION跨域

稍微大一点的网站,通常都会有不只一个服务器,每个服务器运行着不同的功能模块或者不同的子系统,他们使用不同的二级域名,比如www.a.com、i.a.com、bbs.a.com。而一个整体性强的网站,用户系统是统一的,即一套用户名、密码在整个网站的各个子系统中都是可以登录使用的。各个服务器共享用户数据是比较容易实现的,只需要在后端放个数据库服务器,各个服务器...

zabbix proxy配置实战案例

            zabbix proxy配置实战案例                                      作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 一.zabbix proxy概述   上一篇博客我们分享了zabbix agent有两种工作模式,即主动模式和被动模式,默认是被动模式,主动模式需要我们手动...