2020年11月12日17:20:52 MYSQL事务 王凯玉
事务的定义
事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成
存储引擎
默认的innodb可以满足大部分并发读写 、NDB适用于集群 这两个都支持事务
事务的四大特性
最终都是为了保证一致性
- 原子性 - 事务不可分割,是一个逻辑单位
- 一致性 - 数据库的自身完整性的约束,不能被破坏,在用户的代码中控制
- 隔离性 - 有很多事务去同时操作一张表,这种并发操作应该是互不干扰的
- 持久性 - 对数据库进行增删改的操作时,只要事务提交成功,结果应该是永久性的,不管数据库是崩溃了还是重启了,数据都不会恢复到之前的状态
数据库什么时候会出现事务?
执行一个增删改的语句的时候 自动开启事务
-
start transaction 手动开启事务
-
begin 手动开启事务
-
commit 提交
回滚和提交都可以结束事务,在图形化界面里 断开连接 会自动回滚
事务可以去锁定一行数据,在结束事务的时候会释放锁
事务并发会带来什么问题?
-
脏读(READ UNCOMMITTED)
一个事务读取到了其他事务还没有提交的数据,造成前后两次读取的结果不一致
(没有提交的数据在内存的缓冲池中 不会写入到磁盘中)
-
不可重复读(READ COMMITTED)
一个事务读取到了其他事务已提交的数据,造成前后两次读取结果不一致
-
幻读(REPEATABLE READ)
新增数据 造成事务的两次读取结果不一致
总结: 事务并发的三大问题,都是数据库读一致性的问题
? 必须由数据库提供一定的事务隔离机制来解决。
事务的四种隔离级别(SQL92标准)
-
未提交读(Read Uncommitted):一个事务可以读取到其他事务未提交的数据,会出现脏读 这最低的事务隔离级别
-
已提交读(Read Committed):解决脏读,但是不能解决不可重复读的问题
-
可重复读(Repetable Read):解决脏读和不可重复读,不能解决幻读
-
串行化(Serializable):解决事务并发的所有问题,事务一个个排队执行 没有了并发
副作用:执行速度慢(操作一张数据表的时候 其他事务不能做操作,并发效率降低,生产环境中不会使用)
MYSQL比较贴近这个标准,事务隔离级别越高,支持的并发度就越低。
”可重复读“:在innodb中 已经解决了所有问题
Q:想要保证一个事务中前后两次读取数据结果一致?
A:- 在读取数据之前,加锁,组织其他事务对数据进行修改
? - 生成一个数据请求时间点的一致性数据快照,用这个快照提供一定级别的一致性读取
MYSQL中的锁
从锁的粒度划分:行锁、表锁
从锁的用法划分:乐观锁、悲观锁
从锁的类型划分:
-
排他锁:又叫写锁,不能和其他锁并存,一个事务获取了一个数据行的排他锁,其他事物就不能再获取这个锁,只有获取了排他锁的事务才能操作数据
# 加锁 - 自动:delete/update/insert # 默认上锁 - 手动:select * from student where id = 1 FOR UPDATE;
-
共享锁:又叫读锁,多个事务都可以共享这把锁,都能访问到数据,但是只读不能修改。
# 加锁 slect * from student where id = 1 LOCK IN SHARE MODE; # 释放 (释放共享锁就是事务的结束) commit/rollback ;
锁的作用:竞争资源