前言

一、事务是什么?

事务(Transaction),个别是指要做的或所做的事件。在计算机术语中是指拜访并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务完结(end transaction)之间执行的整体操作组成。

二、事务四大个性

1.原子性

事务是数据库的逻辑工作单位,事务中蕴含的各操作要么都做,要么都不做

2.一致性

事 务执行的后果必须是使数据库从一个一致性状态变到另一个一致性状态。因而当数据库只蕴含胜利事务提交的后果时,就说数据库处于一致性状态。如果数据库系统 运行中产生故障,有些事务尚未实现就被迫中断,这些未实现事务对数据库所做的批改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不统一的状态。

3.隔离性

一个事务的执行不能其它事务烦扰。即一个事务外部的操作及应用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能相互烦扰。

4.持久性

也称永久性,指一个事务一旦提交,它对数据库中的数据的扭转就应该是永久性的。接下来的其它操作或故障不应该对其执行后果有任何影响。

三、环境筹备

MySQL:5.7
winows 10
Navicate for Mysql 11.1

脚本和数据库筹备

筹备一张test表和简略插入几条数据,主键id列和年龄age列

DROP TABLE IF EXISTS `test`;。CREATE TABLE `test` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `age` int(11) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;-- ------------------------------ Records of test-- ----------------------------INSERT INTO `test` VALUES ('1', '2');INSERT INTO `test` VALUES ('2', '10');INSERT INTO `test` VALUES ('3', '4');INSERT INTO `test` VALUES ('4', '5');INSERT INTO `test` VALUES ('5', '6');

查问主动提交状态

show VARIABLES like 'autocommit'

勾销主动提交

set autocommit = off;

查问全局事务

select @@global.tx_isolation;

四、事务的几种隔离级别和验证

1.读未提交(READ UNCOMITTED)

2.读提交(READ COMMITTED)

3.可反复读(REPEATABLE READ)

4.串行化(SERIALIZABLE)


测试开始

事务级别为RU-读未提交;(产生脏读景象)

set global transaction isolation level read uncommitted;

#设置实现后,只对之后新起的 session 才起作用,对曾经启动 session 有效。如果用 shell 客户端那就要从新连贯 MySQL,如果用 Navicat 那就要创立新的查问窗口。

创立新的查问接口

事务1执行update语句

BEGIN;update  test set age ='7' where id ='2';COMMIT

事务B执行select语句

begin;select * from test where id =2

事务1并未提交,事务2进行查问的时候,age的值曾经是7了。

#读未提交,其实就是能够读到其余事务未提交的数据,但没有方法保障你读到的数据最终肯定是提交后的数据,如果两头产生回滚,那就会呈现脏数据问题,读未提交没方法解决脏数据问题。

事务级别为RC-读提交;(产生不可反复度景象)

RC-读提交;

set global transaction isolation level read committed;

事务1 执行查问age值的操作,此时age的值为6

begin;select * from test where id =2

事务2 执行update操作,更新age的值为6

BEGIN;update  test set age ='10' where id ='2';COMMIT

事务1再次查问执行select,发现此时age的值扭转了,变成了10.


在同一事务中(本例中的事务B),事务的不同时刻同样的查问条件,查问进去的记录内容是不一样的,事务A的提交影响了事务B的查问后果,这就是不可反复读。

事务级别为RR-可反复读;(产生幻读景象)

set global transaction isolation level repeatable read;

事务1第一次查问是空的后果

事务2 第二次查问还是空的后果

事务1 中执行插入同样数据的操作,发现报错。

总结

论断:在rr级别下,MySQL InnoDB并不保障防止幻读,没有齐全解决快照读下的幻读问题,mysql应用mvcc利用历史数据只是局部防止了幻读(在某些场景看上去躲避了幻读),要完全避免,须要手动加锁将快照读调整为以后读(mysql不会主动加锁)。

Select  * from test where id = ‘8’ for update;

而后mysql应用next-key完全避免了幻读。