详解MySQL事务(超详细)

目录

1、查看存储引擎

2、事务的属性:

1. 原子性(Atomicity)

2. 一致性(Consistency)

3. 隔离性(Isolation)

4. 持久性(Durability)

3、事务的隔离级别

4、不同的隔离级别会产生的问题

5、mysql事务隔离级别实战

①查看当前事务隔离级别:

②设置当前mysql的事务隔离级别(注,要在命令行中执行才有效)

③read uncommitted的脏读演示:

④read committed规避脏读和read committed的不可重复读的演示

⑤repeatable read避免不可重复读与repeatable read的幻读

⑥serializable解决幻读问题

⑦总结

 


      

事务由单独单元的一个或多个SQL语句组成,在这个单元中,每个MySQL语句是相互依赖的。而整个单独单元作为一个不可分割的整体,如果单元中某条SQL语句一旦执行失败或产生错误,整个单元将会回滚。所有受到影响的数据将返回到事物开始以前的状态;如果单元中的所SQL语句均执行成功,则事务被顺利执行。

       即开始事务后执行的所有SQL都是一个整体,一个单元,要么都执行,要么都不执行。这里不执行的意思就row back即回滚,就是回到事务执行前的状态。

1、查看存储引擎

在mysql中,有不同的存储引擎,有些存储引擎支持事务,有些不支持。现在用的最多的是innodb,myisam ,memory

其中innodb支持事务,而 myisam、memory等不支持事务

①查看当前存储存储引擎:

show engines;

2、事务的属性:

1. 原子性Atomicity

       原子性是指事务是一个不可分割的工作单位,事务中的操作要么 都发生,要么都不发生。

2. 一致性Consistency

       事务必须使数据库从一个一致性状态变换到另外一个一致性状态

3. 隔离性Isolation

       事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个 事务内部的操作及使用的数据对并发的其他事务是隔离的,并发 执行的各个事务之间不能互相干扰。

4. 持久性Durability

       持久性是指一个事务一旦被提交,它对数据库中数据的改变就是 永久性的,接下来的其他操作和数据库故障不应该对其有任何影

3、事务的隔离级别

Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLEOracle 默认的事务隔离级别为: READCOMMITED

Mysql 支持 4 种事务隔离级别. Mysql 默认的事务隔离级别: REPEATABLE READ

4、不同的隔离级别会产生的问题

脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段. 之后, T2 回滚, T1读取的内容就是临时且无效的.

不可重复读: 对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了.

幻读: 对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行.

5、mysql事务隔离级别实战

每启动一个 mysql 程序, 就会获得一个单独的数据库连接. 个数据库连接都有一个全局变量 @@tx_isolation, 表示当前的事务隔离级别.

①查看当前事务隔离级别:

SELECT @@tx_isolation;

可知mysql事务的默认级别是可重复读

②设置当前mysql的事务隔离级别(注,要在命令行中执行才有效)

set session transaction isolation level read uncommitted;
SELECT @@tx_isolation;

③read uncommitted的脏读演示:

先创建一个表:

开启事务,并修改一列数据

重新打开一个命令行,注意:每启动一个 mysql 程序, 就会获得一个单独的数据库连接,所以新打开的事务隔离级别还是repeatable read:

若此时用另一个mysql程序查看表时,发现对应的值修改为王五了,若此时第一个mysql程序执行回滚,则读到的数据又变为张三了,此时就出现了脏读情况即读到了脏数据。

④read committed规避脏读和read committed的不可重复读的演示

将两个mysql程序都设置为read committed隔离级别

注:之前的事务虽然回滚了,但还没有提交,要进行下一个操作的话先执行commit;提交事务

 可以发现蓝色这边的mysql程序读到的是未提交的数据,就可以避免脏读

黑色这边提交之后,蓝色才能读到:

但也导致了两次连续的查询 查询到的结果不一样,就导致了不可重复读。

⑤repeatable read避免不可重复读与repeatable read的幻读

提交之前的事务并设置事务为可重复读

先看一下现在表有什么数据,不要到时候混乱了: 

黑色这边修改数据,蓝色这边查看数据还是原来的,规避了脏读

黑色这边提交,蓝色这边读到的仍然是原来的数据

只有当蓝色这边也提交了才能看到修改的数据,这就能使蓝色这边事务进行过程中读到的数据是一致的。

再次开启事务,演示幻读:

黑色这边先查询有两个数据,此时蓝色这边插入了一条数据并提交了,此时黑色这边就会出现一个问题就是我明明是要修改两个数据的,结果却修改了3个,就导致了幻读。

⑥serializable解决幻读问题

首先还是老样子,提交之前的事务,然后设置事务为serializable

此时在黑色事务打开时,在蓝色这边对数据进行插入操作,发现蓝色这边的操作执行不了,这就是serializable的隔离机制,即之前有事务在进行操作,新的事务要对表进行增删改时就会阻塞改操作,知道当前事务提交才能修改:

那个插入数据之所以没成功,是等待时间太长了,被系统杀死了,大家在操作的时候就不要让另一个事务等太久。

⑦总结

mysql默认隔离级别是repeatable read,因为serializable的缺点很明显,虽然能大大提高安全性,但效率太低了。

注意:serializable名字叫可串行化,并不是说使用了serializable隔离级别所有的事务都要串行执行,它允许事务并发执行,但系统必须保证并发调度是可串行的,即我允许你并行执行,但要求你的并发调度不致发生错误,即如果你的另一个事务只进行查数据,那当然对我的事务无影响,我就允许你执行,但如果你另一个事务有增删改这些操作,就会被阻塞以保障不发生错误。

猜你喜欢

转载自blog.csdn.net/tyh1579152915/article/details/109381299
今日推荐