MySQL:事务隔离
一、基本概念
事务就是要保证一组数据库操作,要么全部成功,要么全部失败。
在MySQL中,事 务支持是在引擎层实现的。你现在知道,MySQL是一个支持多引擎的系统,但并不是所有的引 擎都支持事务。比如MySQL原生的MyISAM引擎就不支持事务,这也是MyISAM被InnoDB取代 的重要原因之一
二、事务的启动方式
显式启动事务
启动事务:begin或者start transaction
提交:commit
回滚:rollback
隐式启动事务
有些客户端连接框架会默认连接成功后先执行一个set autocommit=0的命令。这就导致接下来的 查询都在事务中。
set autocommit=0 ,这个命令会将这个线程的自动提交关掉。意味着如果你只执行一个 select语句,这个事务就启动了,而且并不会自动提交。这个事务持续存在直到你主动执行 commit 或 rollback 语句,或者断开连接
因此,我会建议你总是使用set autocommit=1 , 通过显式语句的方式来启动事务
相关sql
查看事务提交方式(1:表示自动提交,0:表示手动提交)
select @@AUTOCOMMIT;
修改事务的提交方式
select @@AUTOCOMMIT = 数字;
数据库查询隔离级别
select @@tx_isolation;
设置数据库隔离级别(需要重新连接才可以查看修改之后的数据)
set global transaction isolation level 级别字符串;
set session transaction isolation level 级别字符串;(改变当前会话)
三、隔离级别
事务四大特征
- 原子性(Atomicity):事务是一个完整的操作,事务的各步操作是不可以拆分的,要嘛都执行,要嘛不执行
- 一致性(Consistency):事务执行之前和执行之后都必须处于一致性状态
- 隔离性(Isolation):多个事务之间互不干扰
- 永久性(Durability):事务完成后,把数据永久保存到磁盘中
事务的隔离级别
序号 | 隔离级别 | 名称 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 |
---|
1 | READ UNCOMMITTED | 读未提交 | YES | YES | YES | | 2 | READ COMMITTED | 读已提交 | NO | YES | YES | Oracle 数据库默认级别 | 3 | REPEATABLE READ | 可重复读 | NO | NO | YES | MySQL 数据库默认级别 | 4 | SERIALIZABLE | 串行化 | NO | NO | NO | |
- 脏读: (读未提交) 当一个事务正在访问数据并且对数据进行修改的时候,还没有对修改的数据进行提交,然后另外一个事务访问到这个数据
- 不可重复读: (读已提交) 指在一个事务内多处读取同一个数据,在一个事务还没有结束的时候,另外一个事务也对他进行了修改,导致了俩次读取的数据不一样。
- 幻读: (不可重复读) 它发生在一个事务读取到了几行数据,接着另外一个事务插入了一些数据,然后第一个事务机会发现多了一些不存在的数据,跟产生了幻觉一样,称为幻读。
四、案例
准备数据
create database test;
use test;
create table user(age int) engine=InnoDB;
insert into user(age) values(1);
案例:读未提交
修改隔离级别:
set global transaction isolation level read uncommitted;
查看隔离级别:(这里需要断开连接后,重新连接生效)
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到
案例:读已提交
修改隔离级别:
set global transaction isolation level read committed;
读已提交是指,一个事务提交之后,它做的变更才会被其他事务看到
案例:可重复读
修改隔离级别
set global transaction isolation level repeatable read;
可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一 致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
案例:串行化
修改隔离级别
set global transaction isolation level serializable;
串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突 的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。
|