排它锁
其他事务不能读取和修改
MySQL有三种级别:页级、表级、行级。
表级锁:开销小,加锁快;锁定粒度大,发生锁冲突的概率最高,并发度最低。
表级锁性能问题较大,如果出现locked状态,一般来说就是表锁的锅
行级锁:开销大,加锁慢;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;锁定粒度界于表锁和行锁之间,并发度一般
共享锁
其他事务可以读取,不能修改
MVCC
Multi-Version Concurrent Control 多版本并发控制
原理
保存数据快照,操作副本。也就是在不同事物里面,因为副本的原因同一时间看见的同一数据可能是不一样的
不同副本之间用版本号区别,数据库会内置系统版本号,每经过一次事物就将版本号+1
工作的隔离级别
mysql实现:
REPEATABLE READ
READ COMMITTED
在这两个隔离级别才会使用mvcc
mysql innodb
乐观锁
悲观锁
- 获取结果集之后,对结果集加行锁
- 对于非主键、非索引字段查询加表锁
sql语句
实现:通过for update(在没有指定主键的情况下,innodb的行锁将变成表锁)
解决:幻读
引发:死锁(两个(或以上)的Session加锁的顺序不一致)
Jpa实现
- 线程加上事务: @Transactional(isolation = Isolation.READ_COMMITTED) 等
注意:事务注解添加的时候嵌套容易引发死锁
- 自己写的查询语句注解:@Lock(value = LockModeType.PESSIMISTIC_WRITE)
发生死锁原因
- 业务逻辑问题,使得上锁顺序颠倒。锁表和锁行都可能发生
- 共享锁上升到排它锁
- 在锁有索引的情况下,如果在索引里面有多个添加索引的字段,字段顺序相反
近期评论