mysql中的锁(悲/乐观锁结合事务的使用)

锁分类

  1. 按操作划分:DML锁,DDL锁
  2. 按锁的粒度划分:表级锁、行级锁、页级锁
  3. 按锁级别划分:共享锁、排他锁
  4. 按加锁方式划分:自动锁、显示锁
  5. 按使用方式划分:乐观锁、悲观锁

乐观锁实现方法

  1. 每次获取商品时,不对该商品加锁。
  2. 在更新数据的时候需要比较程序中的库存量与数据库中的库存量是否相等,如果相等则进行更新
  3. 反之程序重新获取库存量,再次进行比较,直到两个库存量的数值相等才进行数据更新。

乐观锁适用于 读多写少的操作

乐观锁 与事务的实现

def post(self,request):
    with transaction.atomic():
        save_id = transaction.savepoint()

        try:
          	
            #死循环
            while True:
              #先查询数据库
           		 user = User.objects.filter(age=30).first()
                ...
                ...
                ...
                #判断一次查询的结果跟本次查询结果是否一致
                result = User.objects.filter(age=30).update(age = 31)
                #result=0时不一致,继续循环
                if result==0:
                    continue
                #res!=0是,说明找到了那个数据并修改成功,则跳出死循环,继续执行
                else:
                    break
            transaction.savepoint_commit(save_id)
        except:
            transaction.savepoint_rollback(save_id)
    return  Response

悲观锁实现方法

  1. 每次获取商品时,对该商品加排他锁。
  2. 也就是在用户A获取获取 id=1 的商品信息时对该行记录加锁,期间其他用户阻塞等待访问该记录。

悲观锁适用于 写多读少的操作

悲观锁 与事务的实现

def post(self,request):
    with transaction.atomic():
        save_id = transaction.savepoint()
        try:
          	#使用悲观锁来操作数据库
            user = User.objects.select_for_update().filter()
            ...
            ...
            ...
            ...
            user.save()
            transaction.savepoint_commit(save_id)
        except:
            transaction.savepoint_rollback(save_id)

    return  Response

排它锁

  1. 排它锁又叫写锁,如果事务T对A加上排它锁,则其它事务都不能对A加任何类型的锁。获准排它锁的事务既能读数据,又能写数据。
  2. 用法 : SELECT … FOR UPDATE

共享锁(share lock)

  1. 共享锁又叫读锁,如果事务T对A加上共享锁,则其它事务只能对A再加共享锁,不能加其它锁。
  2. 获准共享锁的事务只能读数据,不能写数据。
  3. 用法: SELECT … LOCK IN SHARE MODE;

你可能感兴趣的:(mysql中的锁(悲/乐观锁结合事务的使用))