发布日期:
2024-09-11
文章字数:
1.2k
阅读时长:
4 分
阅读次数:
事务
- ACID
- 原子性(Atomicity) :事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行
- 一致性(Consistent) :在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性
- 隔离性(Isolation) :数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然
- 持久性(Durable) :事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持
- 并发事务处理带来的问题
- 更新丢失(Lost Update)或脏写:最后的更新覆盖了由其他事务所做的更新
- 脏读(Dirty Reads):事务A读取到了事务B已经修改但尚未提交的数据
- 不可重读(Non-Repeatable Reads) :事务A内部的相同查询语句在不同时刻读出的结果不一致,不符合隔离性
- 幻读(Phantom Reads):事务A读取到了事务B提交的新增数据,不符合隔离性
- 事务隔离级别:事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使事务在一定程度上“串行化”进行,这显然与“并发”是矛盾的
- 不同的应用对读一致性和事务隔离程度的要求也是不同的
- 当前数据库的事务隔离级别:
show variables like 'tx_isolation';
- 设置事务隔离级别:
set tx_isolation='REPEATABLE-READ';
- Mysql默认的事务隔离级别是可重复读
- 4 种事务隔离级别
- 读未提交:
set tx_isolation='read-uncommitted';
- 读已提交:
set tx_isolation='read-committed';
- 可重复读:
set tx_isolation='repeatable-read';
- 使用了MVCC(multi-version concurrency control)机制
- select操作不会更新版本号,是快照读(历史版本)
- insert、update和delete会更新版本号,是当前读(当前版本)
- 使用了间隙锁
- 串行化:
set tx_isolation='serializable';
- 这种隔离级别并发性极低,开发中很少会用到
- 读操作会获得共享锁,写操作会获得排他锁
- 使用了间隙锁

锁
- 锁分类
- 乐观锁:version
- 悲观锁:读锁(共享锁,S锁(Shared))和写锁(排它锁,X锁(eXclusive))
- 读锁会阻塞写,但是不会阻塞读
- 写锁则会把读和写都阻塞
- 从对数据操作的粒度分:表锁和行锁
- 无索引行锁会升级为表锁:InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为表锁
- 表锁
lock table 表名称 read(write)
show open tables;
查看表上加过的锁
unlock tables;
- 行锁:InnoDB支持事务(TRANSACTION)和行级锁
- MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行update、insert、delete操作会自 动给涉及的表加写锁
- InnoDB在执行查询语句SELECT时(非串行隔离级别),不会加锁。但是update、insert、delete操作会加行锁
- 锁定某一行还可以用 lock in share mode(共享锁) 和 for update(排它锁)
- 通过检查InnoDB_row_lock状态变量来分析系统上的行锁的争夺情况
- Innodb_row_lock_time_avg (等待平均时长)
- Innodb_row_lock_waits (等待总次数)
- Innodb_row_lock_time(等待总时长)
- 间隙锁:就是两个值之间的空隙,在某些情况下可以解决幻读问题
- 这个范围所包含的所有行记录(包括间隙行记录)以及行记录所在的间隙里
- 临键锁(Next-key Locks):是行锁与间隙锁的组合
- 查看INFORMATION_SCHEMA系统库锁相关数据表
INFORMATION_SCHEMA.INNODB_TRX
查看事务
INFORMATION_SCHEMA.INNODB_LOCKS
查看锁
INFORMATION_SCHEMA.INNODB_LOCK_WAITS
查看锁等待
kill trx_mysql_thread_id
释放锁,trx_mysql_thread_id
可以从 INNODB_TRX
表里查看到
show engine innodb status
查看锁等待详细信息
- 死锁
show engine innodb status
- 大多数情况mysql可以自动检测死锁并回滚产生死锁的那个事务
- 锁优化
- 尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
- 合理设计索引,尽量缩小锁的范围
- 尽可能减少检索条件范围,避免间隙锁
- 尽量控制事务大小,减少锁定资源量和时间长度,涉及事务加锁的sql尽量放在事务最后执行
- 尽可能低级别事务隔离