一、锁的分类
- 按操作划分:DML锁、DDL锁
- 按锁的粒度划分:表级锁、行级锁、页级锁
- 按锁级别划分:共享锁、排他锁
- 按加锁方式划分:自动锁、显示锁
- 按使用方式划分:乐观锁、悲观锁
二、锁的实现
2.1 乐观锁的实现方法
- 每次获取商品时,不对该商品加锁。
- 在更新数据的时候需要比较程序中的库存量与数据库中的库存量是否相等,如果相等则进行更新
- 反之程序重新获取库存量,再次进行比较,直到两个库存量的数值相等才进行数据更新。
#### 乐观锁实现加一操作代码
# 我们可以看到,只有当对数量-1操作时才会加锁,只有当程序中值和数据库中的值相等时才正真执行。
'''
//不加锁
select id,name,stock where id=1;
//业务处理
begin;
update shop set stock=stock-1 where id=1 and stock=stock;
commit;
'''
2.2 悲观锁的实现
- 每次获取商品时,对该商品加排他锁。
- 也就是在用户A获取获取 id=1 的商品信息时对该行记录加锁,期间其他用户阻塞等待访问该记录。
#### 悲观锁实现加一操作代码
# 我们可以看到,首先通过begin开启一个事物,在获得shop信息和修改数据的整个过程中都对数据加锁,保证了数据的一致性。
begin;
select id,name,stock as old_stock from shop where id=1 for update;
update shop set stock=stock-1 where id=1 and stock=old_stock;
commit;
2.3 排它锁的实现
又叫写锁
- 如果事务T对A加上排它锁,则其它事务都不能对A加任何类型的锁。获准排它锁的事务既能读数据,又能写数据。
- 用法 : SELECT … FOR UPDATE
2.4 共享锁的实现
- 共享锁又叫
读锁
,如果事务T对A加上共享锁,则其它事务只能对A再加共享锁,不能加其它锁。 - 获准共享锁的事务只能读数据,不能写数据。
- 用法: SELECT … LOCK IN SHARE MODE;