01.mysql中的锁
1.1 锁分类
- 
按使用方式划分:乐观锁、悲观锁
- 
按锁级别划分:共享锁、排他锁
- 
按锁的粒度划分:表级锁、行级锁、页级锁
- 
按操作划分:DML锁,DDL锁 
- 
按加锁方式划分:自动锁、显示锁 
1.2 共享锁和排它锁
- 
共享锁( 读锁)- 共享锁又叫读锁,如果事务T对A加上共享锁,则其它事务只能对A再加共享锁,不能加其它锁。
- 获准共享锁的事务只能读数据,不能写数据。
- 用法: SELECT … LOCK IN SHARE MODE;
 
- 
排它锁( 写锁)- 排它锁又叫写锁,如果事务T对A加上排它锁,则其它事务都不能对A加任何类型的锁。获准排它锁的事务既能读数据,又能写数据。
- 用法 : SELECT … FOR UPDATE
 
1.3 乐观锁和悲观锁
2.3.1 悲观锁:写少读多
悲观锁(Pessimistic Lock)
- 
定义: 
 悲观锁假设会发生冲突,因此在读取数据时就加锁,直到操作完成才释放锁,确保只有一个事务能够对数据进行操作。悲观锁会直接阻塞其他事务的访问,直到当前事务完成。
- 
实现方式: 1.使用数据库的锁机制,例如 SELECT … FOR UPDATE 来锁定数据行。 
 2.在事务开始时,锁定目标记录,其他事务必须等待当前事务提交或回滚后才能操作被锁定的数据。
- 
使用场景: 
 1.高并发系统: 当并发较高时,使用悲观锁可以避免数据冲突,通过加锁保证事务的顺序性。
 2.关键性的数据更新: 例如库存扣减等操作,确保数据的一致性和准确性。
 3.长时间操作的事务: 当事务需要进行复杂的操作且无法快速完成时,使用悲观锁可以防止其他事务对数据的更改,避免脏读或丢失更新。
| 1 | #### 悲观锁实现加一操作代码 | 
2.3.2 乐观锁:读多写少
乐观锁(Optimistic Lock)
- 定义:
 乐观锁假设不会发生冲突,因此在读取数据时不加锁,只有在提交数据时才会进行冲突检查。通常通过版本号或时间戳来检测是否发生了并发修改。
实现方式:
1.在数据表中添加一个版本号(version)或时间戳字段。
2.在读取数据时,客户端读取数据的同时也会读取这个版本号或时间戳。
3.在更新数据时,客户端会将数据提交到数据库,并同时检查提交时的版本号或时间戳是否和读取时一致。如果一致,表示没有其他事务修改该数据,更新成功;否则,更新失败,需要重新读取数据并再次提交。
使用场景:
- 低并发系统: 在高并发情况下,乐观锁的性能较差,因为冲突的概率增加,但在低并发下非常适合使用。
- 操作不频繁的资源: 当数据更新的频率不高时,乐观锁能够有效减少数据库的锁竞争。
- 非关键性的数据: 数据冲突后可以容忍重试的场景,如某些临时数据的处理。
| 1 | #### 乐观锁实现加一操作代码 | 
1.4 行级锁 & 表级锁
- 行级锁(写多读少)开销大,加锁慢,锁定粒度最小,发生锁冲突概率最低,并发度最高
- 表级锁(适合大量的读操作)开销小,加锁快,锁定粒度大、发生锁冲突最高,并发度最低
__END__
