事务
事务可以简单的理解为一组SQL语句,要么全部成功执行,要么都不执行。
show variables like 'autocommit';
set autocommit = 0;
begin;
select ...
commit
特点(ACID)
- Atomicity: 一个事务被视为最小单元,要么全部执行成功,要么全部失败回滚
- Consistency: 数据在事务执行周期内,是一致的
- Isolation: 事务之间是隔离的
- Durability: 事务一旦提交,就永久保存到数据库
事务并发的问题
- Lost Update: 多个事务对同一数据进行更新,后者会覆盖
- Dirty Reads: 一个事务对一个数据做修改,但未提交,另一个数据读取到这些脏数据,并做进一步处理
- Non-Repeatable Reads: 同一个事务在不同时间读取的数据不一致, 针对修改
- Phantom Reads: 在不同时间读取的不一样,针对新增,例子
锁
乐观锁
乐观锁认为一般情况下数据不会发生冲突,所以在数据提交更新的时候,才会对数据的冲突进行检测,数据库层面没有实现,需要自己程序实现。可以使用数据版本(version)或时间戳实现,比如MVCC。
悲观锁
悲观锁认为每次取数据的时候都会被修改,所以每次拿数据时,都会上锁。s锁和x锁都是悲观锁。
类型
- 共享锁(读锁,s锁):会阻塞其他事务修改数据, select … lock in share mode;
- 排他锁(写锁,x锁):会阻塞其他事务读和修改数据, select … for update;
粒度
- 表锁:锁住全表
- 行锁:InnoDB默认,没有索引或锁定全表
死锁
未完,待续。。。
隔离级别
select @@tx_isolation;
set [ global | session ] transaction isolation level Read uncommitted | Read committed | Repeatable | Serializable;
- Read uncommitted: 未提交读,允许脏读,也就是能读到其他事务中未提交的数据
- Read committed: 已提交读,只能读到已提交的数据,Oracle等数据库默认
- Repeatable read: 可重复读,在同一事务的查询都是在事务开始一致的,Innodb默认
- Serializable: 可串行化,每次都是要获得表级共享锁,读写都相互阻塞