My SQL 事务 & 事务的隔离级别
1、事务
① 概念
事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内 的所有SQL都将被取消执行
② 特点
一个事务中如果有一个数据库操作失败,那么整个 事务的所有数据库操作都会失败,数据库数据就会 回滚到该事务开始之前的状态
③ 限制
MySQL数据库中仅InnoDB和BDB类型的数据库表 支持事务
④ 事物的四大特性
原子性
-- 意味着数据库中的 事务执行是作为原子粒度。即不可再分,整个语句要么 执行,要么不执行
一致性 (重要)
-- 即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
隔离性
-- 为了让不同的事务之间相互不存在干扰,就需要对事务的操作进行隔离,事务的隔离性也就是将操作同一个数据的事务相互分离,让操作之间分开有序的执行
持久性
-- 意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚
拓展:
# 用什么方式实现事务的隔离性?
-- 答: 通常数据库里都是采用锁的机制,保证事务之间的隔离性
1、MySql中的锁
① 锁分类: 基于锁的属性分类:共享锁(读锁、S锁)、排他锁(写锁,X锁)
② 基于锁的粒度分类:表锁、行锁(记录锁、间隙锁、临键锁)。
③ 基于锁的状态分类:意向共享锁、意向排它锁。
2、事务的隔离级别
事务隔离级别:
锁等级 | 锁的解释 |
---|---|
READ_UNCOMMITTED | 读未提交 |
READ_COMMITTED | 读提交(不可重复读) |
REPEATABLE_READ | 可重复读 |
SERIALIZABLE | 串行化 |
注意:
每个隔离级别都针对事务并发问题中的一种或几种进行解决,事务级别越高,解决的 并发事务问题也就越多,同时也意味着加的锁就越多,所以性能也会越差。
3、 事务并发问题
在事务并发执行的时候,如果不进行事务隔离,那么就会产生脏写、脏读、 不可重复读、幻读的问题。
4、事务的隔离级别解决的问题
# 1.READ_UNCOMMITTED
事务读取:不加锁
事务写入:加写锁
解决问题:赃写
存在问题:脏读、不可重复读、幻读
# 2.READ_COMMITTED
事务读取:加读锁
事务写入:加写锁
解决问题:赃写、脏读
存在问题:不可重复读、幻读
# 3.REPEATABLE_READ
事务读取:加读锁
注:(每次 select 完不会释放锁,而是事务结束后才释放。如果是 Mysql 的 innodb 还会加间隙锁)
事务写入:加写锁
解决问题:赃写、脏读、不可重复读、幻读(如果是 Mysql 的 innodb 则已解决)
存在问题:幻读(如果是 Mysql 的 innodb 则不存在)
# 4.SERIALIZABLE
不管读取还是修改所有的事务串行化执行,一个事务的执行必须等其他事务结束
⑤ 事务的操作
1、关闭自动提交
# 语法
SET AUTOCOMMIT = 0;
2、开启事务
# 语法
START TRANSACTION;
3、创建事务
# 语法 (事务案例)
update bank set bmoney = bmoney-1000 where bname = '张三';
update bank set bmoney = bmoney+1000 where bname = '李四';
4、提交事务
# 语法
COMMIT;
5、回滚事务
# 语法
ROLLBACK;
注意:【提交事务】 和 【回滚事务】互斥, 只能执行一个
6、开启自动提交
SET AUTOCOMMIT = 1;
2、实现事物的方法
如图所示:
事务代码案例:
-- 关闭自动提交
SET AUTOCOMMIT = 0;
-- 开启事务
START TRANSACTION;
-- 创建事务
update bank set bmoney = bmoney-1000 where bname = 'XX';
update bank set bmoney = bmoney+1000 where bname = 'YY';
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
-- 开启自动提交
SET AUTOCOMMIT = 1;