1.概述
1 什么是事务?
- 事务对应的单词是:Transaction
- 事务是:
- 一个最小的不可再分的工作单元
- 通常一个事务对应了一个完整的业务
- 而一个完整的业务需要批量的DML语句(insert,delete,update)共同联合完成
- 事务这和DML语句有关系(只有DML语句有事务)
- 批量的DML语句共有多少条,这和业务逻辑有关系。业务逻辑不同,DML语句的个数不同
示例:银行转账业务(转账业务是一个完整的事务)
2 事务特征(ACID)
-
原子性(Atomicity)
整个事务中的所有操作,必须作为一个单元全部完成/全部取消(最小单元,不可分割) -
一致性(Consistency)
在事务开始之前与结束之后,数据库都保持一致状态 -
隔离性(Isolation)
一个事务不会影响其他事务的运行 -
持久性(Durability)
在事务完成以后,该事务对数据库所作的更改将持久地保存在数据库之中,并不会被回滚(从内存中到硬盘存储)。
3 基础概念
- 开启事务:Start Transaction
- 事务结束:End Transaction
- 提交事务:Commit Transaction
- 回滚事务:Rollback Transaction
4与事务有关的SQL语句(TCL)
1.commit; —提交
2.rollback; —回滚
2.事务开启/结束的标志
开启标志
任何一条DML语句(insert,delete,update)执行,标志事务的开启。
结束标志
提交/回滚:
提交:成功的结束,将所有的DML语句操作历史记录与底层数据库中的数据进行同步
回滚:失败的结束,将所有的DML语句的操作历史记录全部清空
在事务进行过程中,未结束之前,DML语句是不会更改底层数据库文件中的数据。只将历史操作在内存中完成记录,只在事务成功结束时才会修改底层硬盘中的数据。
1 在mysql中事务演示
注意:在mysql中默认情况下,事务是自动提交的。只要执行DML语句即可开启事务并且提交事务。但是这种机制可以关闭的。**
1.关闭自动提交方式1——start transaction;
基础语法:
手动提交:
start transaction; ----手动开启事务
DML 语句......
DML 语句......
DML 语句......
DML 语句......
commit; ----手动提交
关闭自动提交后进行数据插入:
上图描述:在 1 中对事务自动提交进行关闭,后插入数据,在当前插入窗口是可以查询到插入数据,应为该数据全部存入在内存中,而重新开启另一个终端 2 进行查询是无法查询到插入的数据,因为在 1 中插入的数据并没有进行手动提交
手动提交之后:commit;
手动回滚:
start transaction; ----手动开启事务
DML语句......
DML语句......
DML语句......
DML语句......
rollback; ----手动回滚
关闭自动提交进行插入数据:
回滚后:rollback;
2.关闭自动提交方式2——set autocommit
关闭自动提交
set autocommit = off / set session autocommit = off;
打开自动提交
set autocommit = on / set session autocommit = on;
1.事务自动提交状态查看:
show variables like '%commit%';
2.关闭事务自动提交:
set autocommit = off;
3.开启事务自动提交:
set autocommit = on;
注意:以上打开和关闭事务自动提交,只对当前会话有效!
3.事务隔离性(isolation)
事务与事务之间具有一定的隔离性!
1 隔离级别(4个)
-
读未提交 read uncommitted(最低隔离,存在于理论之中)
事务a和事务b,事务a未提交的数据,事务b可以读取到(该行为读取到的数据称为“脏数据”/“脏读(drity read)”),数据库默认的隔离级别一般高于该级别
-
读已提交 read committed
事务a和事务b,事务a提交的数据,事务b才能读取到,该隔离可以避免脏读但是会导致数据不可重复读取
Oracle数据库管理系统默认隔离级别为:read committed
-
可重复读 repeatable read
事务a和事务b,事务a提交的数据之后,事务b读取不到,事务b可以重复读取数据。该级别可以避免不可重复读取,但是会导致幻象读。
Mysql数据库管理系统默认隔离级别为:repeatable read
-
串行化 serializable(最高隔离)
事务a和事务b,事务a在操作数据库表中的数据的时候,事务b只能排队等待,这种隔离级别使用较少(吞吐量低,用户体验不好)。该隔离界别可以避免幻象读,每次读取的是数据库中真实存在的数据,并且事务与事务不再并发。
2 设置事务的隔离级别
1.方式一:修改my.ini配置文件
可选项值:
— READ-UNCOMMITTED
— READ-COMMITTED
— REPEATABLE-READ
— SERIALIZABLE
[mysqld]
transaction-isolation = READ-COMMITTED
2.方式二:使用命令的方式设置
格式:
SET [ 无 | GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
可选项值:
— READ UNCOMMITTED
— READ COMMITTED
— REPEATABLE READ
— SERIALIZABLE
例子:
set TRANSACTION ISOLATION LEVEL READ COMMITTED;
3 隔离级别的作用范围
1.作用范围:
-
全局级:对所有会话有效
set GLOBAL TRANSACTION ISOLATION LEVEL
-
会话级:只对当前的会话有效
set SESSION TRANSACTION ISOLATION LEVEL
或者
set TRANSACTION ISOLATION LEVEL
4 查看隔离级别
1.查看当前会话的隔离级别:
select @@tx isolation;
select @@session.tx isolation;
2.查看全局事务隔离级别:
select @@global.tx isolation;
5 并发事务与隔离级别示例
1.读未提交:
read uncommitted
会话1 | 会话2 |
---|---|
set GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 退出DOC窗口 | |
start transaction; | start transaction; |
insert into t_test(name)values(“test”); | select * from t_test;(可查询到会话1插入且未提交的数据) |
2.读已提交:
read committed
会话1 | 会话2 |
---|---|
set GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; 退出DOC窗口 | |
start transaction; | start transaction; |
insert into t_test(name)values(“test”); | select * from t_test;(不可查询到会话1插入且未提交的数据) |
commit; | select * from t_test;(查询到会话1插入并提交的数据) |
3.可重复读:
repeatable read
会话1 | 会话2 |
---|---|
set GLOBAL TRANSACTION ISOLATION LEVEL repeatable read; 退出DOC窗口 | |
use testdatabase; | use testdatabase; |
select * from t_test; | select * from t_test; |
insert into t_test(name)values(“test”); | |
commit; | select * from t_test;(不可查询到会话1插入且提交的数据),只显示上一次查询的数据 |
drop table t_test;(无法删除,需要保证会话2可以重复读取数据,但是与事务无关) |
本文地址:https://blog.csdn.net/qq_19331985/article/details/107637635