什么是数据库的事务
数据库事务的典型场景
- 订单 从下单到支付到扣库存
- 转账 从A扣减到B增加
什么是事务
事务是数据管理系统(DBMS)执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成
那些存储引擎支持事务
这里是可以知道InnoDB
事务的四大特性
- 原子性(Atomicity)
每个单元都执行成功了 - 一致性(Consistent)
比如转账, A减少了对应的数量,B就需要增加对应的数量 - 隔离性(Isolation)
数据之间是互相不影响的 - 持久性(Durable)
只要提交了,数据就会永久存储的
数据库什么时候会出现事务
- 默认数据库的事务是开启的
- 可以手动开启事务
begin 等价于 start transaction
begin;
update xxx set xxx = '';
commit;
rollback;
事务并发带来的问题
- 脏读:事务A两次相同的查询,读取到了事务B未提交的处理结果
- 不可重复读(更新、删除)
- 幻读(插入)
事务并发的三大问题其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决
事务的四种隔离级别
SQL92 ANSI/ISO 标准 http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
- Read Uncommitted(未提交读)
- Read Committed(已提交读):解决脏读
- Repeatable Read(可重复读):解决脏读、不可重复读
- Serializable(串行化):解决事务并发的所有问题(就会导致没有并发了,只能排队执行了)
如果要解决读一致性的问题,保证一个事务中前后两次读取数据结果一致,实现事务隔离,应该怎么做?
第一种:
在读取数据前,对其加锁,放置其他事务对数据进行修改–Lock Based Concurrency Control(LBCC)
第二种:
生成一个数据请求时间点的一致性数据库快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取–Multi Version Concurrency Control (MVCC)
锁的粒度
表锁与行锁的区别:
锁定粒度:表锁 > 行锁
加锁效率:表锁 > 行锁
冲突概率:表锁 > 行锁
并发性能:表锁 < 行锁
问题:MyISAM 和 InnoDB分别支持什么粒度的锁?
MyISAM 是只支持表锁, InnoDB同时支持表锁和行锁
MySQL InnoDB 锁类型
锁的模式 Lock Mode
- 共享锁(行锁)Shared Locks
又称为读锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
加锁方式:
select * from student where id = 1 Lock IN Share Mode;
释放锁:
commit/rollback;
- 排它锁(行锁)Exclusive Locks
又称为写锁,排它锁不能与其他锁并存,如一个事务获取了一个数据行的排它锁,其他事务就不能再获取该行的锁(共享锁、排它锁),只有该获取了排它锁的事务是可以对数据行进行读取和修改
加锁方式:
自动:delete / update / insert 默认加上X锁;
手动:select * from student where id = 1 FOR UPDATE;
- 意向共享锁(表锁)Intention Shared Locks
意向锁是由数据引擎自己维护的,用户无法手动操作意向锁。意向共享锁(Intention Shared Lock,简称IS锁)
表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁 - 意向排它锁(表锁)Intention Exclusive Locks
意向排它锁(Intention Exclusive Lock,简称IX锁)
表示事务准备给数据行加入排它锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁
一个事务要成功锁住一张表的前提没有其他任何事务已经锁定了其中的任意一行
行锁算法
- 记录锁 Record Locks
- 间隙锁 Gap Locks
- 临键锁 Next-key Locks
锁的作用是解决资源竞争的问题