Mysql事务
Posted 水月情缘雪飞飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql事务相关的知识,希望对你有一定的参考价值。
@[TOC]mysql事务
简介
事务四大特征(ACID)
推荐: https://blog.csdn.net/lianghecai52171314/article/details/102782804
原子性:事务是最小单位,不可再分,例如:update … insert … delete …
一致性:所有的DML语句操作,必须同时成功或者同时失败
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read
committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
事务的4个级别
隔离级别:
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
未提交读(READ-UNCOMMITTED) | 是 | 是 | 是 |
已提交读(READ-COMMITTED) | 否 | 是 | 是 |
可重复读(REPEATABLE-READ)[默认级别] | 否 | 否 | 否 |
串行化(SERIALIZABLE ) | 否 | 否 | 否 |
脏读,幻读,不可重复读
脏读[脏数据](Dirty Read): 两个事务,一个事务未提交的数据(commit),另一个事务可以读取到.
不可重复读(NonRepeatable Read):事务A在修改数据,事务B在事务A 数据(修改前)和(修改后),未提交(commit)前,两次读取的数据不一致。
幻读(Phantom Read):是指多个事务执行时发生的一种现象。事务A新增或删除了数据,但是未提交(commit),事务B发现新增或删除的数据,就像幻觉一样。
备注
不可重复读的重点是修改:
同样的条件,你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除:
同样的条件,第 1 次和第 2 次读出来的记录数不一样
查询与设置隔离级别
查询会话事务级别
# mysql 查询会话级别
select @@transaction_isolation; # 查询当前的会话事务级别
select @@global.transaction_isolation; # 查询全局的事务隔离级别
show variables like 'transaction_isolation';
# 8.0以下版本,8.0之后版本废弃
select @@tx_isolation; # 查询当前的会话事务级别
select @@global.tx_isolation; # 查询全局的事务隔离级别
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
设置事务级别
# 未提交读 read uncommitted级别:
set session transaction isolation level read uncommitted;
# 已提交读 read committed级别:
set session transaction isolation level read committed;
# 可重复读 repeatable read级别:
set session transaction isolation level repeatable read;
# 可串行化 serializable级别:
set session transaction isolation level serializable;
# 开始事务
begin;
start transaction;
# 提交事务
commit;
# 回滚
rollback;
示例测试数据
初始化数据表
-- 登录mysql
-- mysql -u root -h 127.0.0.1 -p
-- 创建数据库
-- create database testdb;
use testdb;
drop table if exists user;
CREATE TABLE `user`(
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '名字',
`num` int(11) NOT NULL DEFAULT 0 COMMENT '数量',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 初始数据
INSERT INTO `user` (`name`,`num`) VALUES ('one',0),('two',0),('three',0);
select * from user;
+----+-------+-----+
| id | name | num |
+----+-------+-----+
| 1 | one | 0 |
| 2 | two | 0 |
| 3 | three | 0 |
+----+-------+-----+
未提交读
事务A | 事务B | 无事务 | 备注 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
set session transaction isolation level read uncommitted; | 设置事务级别 开启事务 | ||||||||||||||
set session transaction isolation level read uncommitted; | set session transaction isolation level read uncommitted; | ||||||||||||||
select * from user;
| 原始数据 | ||||||||||||||
INSERT INTO `user` (`name`,`num`) VALUES ('four',0); UPDATE user SET num=10 where id=1; DELETE FROM user where id=3; select * from user;
| |||||||||||||||
select * from user;
| 脏读 事务A数据未提交但是事务B可以读取 | ||||||||||||||
select * from user;
| 虽然未启用事务,但是依然课读取到脏数据 | ||||||||||||||
commit; (事物提交)
| |||||||||||||||
rollback; (事物回滚,无操作)
| |||||||||||||||
select * from tb;
|
已提交读
事务A | 事务B | 无事务 | 备注 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
set session transaction isolation level read committed; begin; | set session transaction isolation level read committed; | set session transaction isolation level read committed; | 设置事物级别 开启事物 | ||||||||||||
select * from user;
| |||||||||||||||
INSERT INTO `user` (`name`,`num`) VALUES ('four',0); UPDATE user SET num=10 where id=1; DELETE FROM user where id=3; select * from user;
| |||||||||||||||
select * from user;
| 看不见事务A数据修改 | ||||||||||||||
select * from user;
| |||||||||||||||
commit; (事物提交)
| 事物A提交 | ||||||||||||||
select * from user;
| 不可重复读, 数据被修改,读取到已提交的数据。 幻读(一种现象), 第一次查询可以看见3,第二次查询3被删除,查询到了4,行不一样了 | ||||||||||||||
rollback; (事物回滚,无操作) | |||||||||||||||
select * from user;
|
可重复读
事务A | 事务B | 无事务 | 备注 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
set session transaction isolation level repeatable read; start transaction; | set session transaction isolation level repeatable read; start transaction; | set session transaction isolation level repeatable read; | 设置事物级别 开启事物 | ||||||||||||
select * from user;
| |||||||||||||||
INSERT INTO `user` (`name`,`num`) VALUES ('four',0); UPDATE user SET num=10 where id=1; DELETE FROM user where id=3; select * from user;
| |||||||||||||||
select * from user;
| 看不见数据修改 | ||||||||||||||
select * from user;
| |||||||||||||||
commit; (事物提交)
| |||||||||||||||
select * from user;
| 未查询到修改,避免 不可重复读取 , | ||||||||||||||
UPDATE user SET num=num+20 where id=1; select * from user;
| 更新后id=1的值为30, 在可重复读的隔离级别下,MySQL采用的是MVCC机制,select 操作不会更新版本号,是快照读(历史版本);而insert、update和delete会更新版本号,是当前读(当前版本) | ||||||||||||||
commit; (事务提交)
| 结束后发现最新数据 | ||||||||||||||
select * from user;
|
串行化
事务A | 事务B | 无事务 | 备注 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
set session transaction isolation level serializable; | set session transaction isolation level serializable; | set session transaction isolation level serializable; | 设置事物级别 开启事物 | ||||||||||||
INSERT INTO `user` (`name`,`num`) VALUES ('four',0); UPDATE user SET num=10 where id=1; DELETE FROM user where id=3; select * from user;
| |||||||||||||||
select * from user; 等待 事物A 执行。。。 | |||||||||||||||
select * from user;
| |||||||||||||||
commit; (事物提交)
| |||||||||||||||
事物A 等待结束,开始执行语句。。。
| 最新数据 | ||||||||||||||
rollback; (事物回滚,无操作)
| |||||||||||||||
select * from user;
|
以上是关于Mysql事务的主要内容,如果未能解决你的问题,请参考以下文章