事务就是一组增删改(dml)语句,该组语句要么全部成功,要么全部失败,比如可以用来处理转账,下面有一个图来帮助理解
我们事务操作的基本流程
就是
开启事务-设置保存点-回滚(或者直接提交)
比如上图,你在10.00,11.00设置保存点
12.00,你发现11.00到12.00的操作有误
你可以回滚到11.00那个保存点b,或者直接回滚到10.00就是第一个图的退回全部事务-这样对应时间段的操作就不会生效
# 演示事务几个操作
# 先建表
CREATE TABLE t27(
id INT,
`name` VARCHAR(32));
# 开启一个事务
START TRANSACTION
# 设置保存点
SAVEPOINT a
# 执行dml操作
INSERT INTO t27
VALUES(100,'tom');
SELECT * FROM t27;
# 再设置一个保存点
SAVEPOINT b
# 执行dml操作
INSERT INTO t27
VALUES(200,'jack');
# 回退到b
ROLLBACK TO b -- 会发现t27回退到执行到b保存点的状态(没有200,jack)
# 继续回退到a
ROLLBACK TO a -- 这个再执行的话,100,tom也没了
ROLLBACK -- 如果这样写就是回退到事务最开始的一个状态
注意:1.当我们提交了(执行完commit操作),就不能回退了,会自动删除所有保存点
2.你不能从一个靠前的保存点回退到靠后保存点,比如你回退到了a点,这个操作会删除所有,从你开始回退那个点到a点中间的所有保存点,就是b点会被删除
3.你没有执行commit操作前,其他连接可能查不到(为什么是可能-涉及到下面的隔离级别)数据的变化,只有commit执行完,数据生效,其他连接肯定可以查看
1.dml操作前没开启事务执行dml语句就自动提交,不能回顾
2.就是开启事务默认就开始事务有一个保存点,你可以通过ROLLBACK来返回事务最开始的状态
3.可以建立多个保存点
4.没有提交前可以回退-回退相关可以上面高亮字有比较详细解释
5.关于引擎最好用innodb
6.两种方式都可以开启事务
事务1和事务2
1.脏读
事务1未提交其作出的dml操作,事务2SELECT的结果却是事务1操作后的,就叫脏读
2.不可重复读-重在修改删除
和脏读不同,事务2进行表的查询,而事务1做dml操作,事务2在事务1提交前查询
和事务2在事务1提交后
查询的结果不同(事务2查询到事务1修改后的结果)
你可能认为这样是对的,然而比如你事务2在10.00连接数据库统计10.00前是数据
你统计到一半,嘎,事务1操作提交,事务2看到10.01进行修改的数据
本身就是想统计10.00前的数据,所以就不合理
3.幻读-重在插入
就类似于不可重复读
最大的不同就是,我们幻读是插入操作
不可重复读是修改和删除操作
1.未提交——>脏读 2. 删除、修改——>不可重复读 3.插入——> 幻读
注意:要先改隔离级别,再启动事务,先启动事务再改的话,开启的事务还是原来的隔离级别
# 演示事务隔离级别
# 1.先开mysql的两个控制台1和2
# 2.查看当前mysql的隔离级别
SELECT @@tx_isolation;
# 对应的隔离级别-可重复读(1和2)
#mysql> SELECT @@tx_isolation;
#+-----------------+
#| @@tx_isolation |
#+-----------------+
#| REPEATABLE-READ |
#+-----------------+
# 3.选择数据库,创建表(控制台1)
USE db02;
CREATE TABLE `account`(
id INT,
`name` VARCHAR(32),
money INT);
# 控制台2也连接一下db02数据库
# 4.把控制台2的隔离级别设置成READ uncommitted - 读不提交的
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
# 5.开启事务(1和2)
START TRANSACTION; -- 控制台一定要+分号
# 6.控制台1随便添加一条记录(100,'tom',1000)别提交
# 7.在控制台2查询该表,看变化,可以查询到添加的数据(一定要先改隔离级别)
这就是我们所谓的脏读现象,可以读到还没有提交的数据
# 控制台2隔离级别改成READ COMMITTED,再开启事务
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
# 这样就不会读取到没有提交的
# 然后控制台1该所有人工资为3000
update account set money=3000;
# 控制台2查询一下account表,查询不到改变
# 控制台1提交事务
commit;
# 再在控制台2查,发现改变了
这就是不可重复读
幻读的话
和上面其实差不多
就是删改操作变成添加数据操作
控制台1添加一个数据后提交
控制台2再次查询观察到添加数据后的改变
其实就这几个隔离级别,前面的话主要说了
前两种 READ UNCOMMITTED和READ COMMITTED,不再次说明了
其实后两种其实就是一个锁的问题(都不会出现本事务读到其他事务操作的信息!)就读你开启事务时间段是对应数据库的信息
控制台1更改且提交
控制台2查询,查询结果不变,不会查询到命令行1的更改
!!!
锁!
这个锁的作用,就是当有别的事务在操作我们要查询的表的时候
你的查询会等待对应操作事务结束后才显示结果
控制台A
我先不进行提交操作
控制台2
尽管我按下了回车也没有显示,只有等控制台1提交后才显示,但是不会显示控制台1改变的结果
然后再控制台1按下回车,控制台2就会直接显示出来
这也就是锁的作用
查看事务隔离级别-查看单个用户的
1.SELECT @@tx_isolation;
查看系统隔离级别-所有用户登陆的默认隔离级别
2.SELECT @@global.tx_isolation;
设置当前事务隔离级别
3.SET SESSION TRANSACTION LEVEL 隔离级别;-后面写你想设置的隔离级别,上面的隔离级别图片有
设置系统当前隔离级别
4.SET GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别; 同上
关于特殊项目需要修改隔离级别
可以自己查一下,主要是修改my.ini文件的操作