首页 > 其他分享 >乐观锁,悲观锁

乐观锁,悲观锁

时间:2023-04-19 15:22:47浏览次数:40  
标签:count transaction savepoint 乐观 book 悲观 sid import

悲观锁乐观锁的实现

from django.shortcuts import render, HttpResponse

# Create your views here.
from .models import Book, Order
from django.db import transaction


### 回滚点的使用
# def seckill(request):
#     with transaction.atomic():
#         # 设置回滚点,一定要开启事务
#         sid = transaction.savepoint()
#         print(sid)
#         try:
#             book = Book.objects.get(pk=1)
#             book.name = 'xxx'
#             book.save() # 没有提交
#             Order.objects.get(pk=1)
#             transaction.savepoint_commit(sid)
#         except Exception as e:
#             # 如发生异常,回滚到指定地方
#             transaction.savepoint_rollback(sid)
#             print('出异常了,回滚')
#
#     return HttpResponse('秒杀成功')


##提交事务后执行的函数
# def send_email():
#     print('发送邮件给卖家了')
#
#
# def seckill(request):
#     with transaction.atomic():
#         book = Book.objects.get(pk=1)
#         book.count = book.count - 1
#         book.save()
#         transaction.on_commit(send_email)
#     return HttpResponse('秒杀成功')



### 悲观锁的使用  mysql的行锁做悲观锁
# Django中使用悲观锁锁定一个对象,需要使用select_for_update()方法。它本质是一个行级锁,能锁定所有匹配的行,如果查询所有,可以锁住整张表,直到事务结束
# import datetime
# import time
# import random
# @transaction.atomic
# def seckill(request):
#     # 锁住查询到的book对象,直到事务结束
#     sid = transaction.savepoint()
#     book = Book.objects.select_for_update().filter(pk=1).first()  # 加悲观锁,指导这个(事务)视图函数结束,锁才释放
#     if book.count > 0:
#         print('库存可以,下单')
#         Order.objects.create(order_id=str(datetime.datetime.now()), order_name='测试订单')
#         # 库存-1,扣减的时候,判断库存是不是上面查出来的库存,如果不是,就回滚
#         time.sleep(4)  # 模拟延迟
#         book.count=book.count-1
#         book.save()
#         transaction.savepoint_commit(sid)
#         return HttpResponse('秒杀成功')
#     else:
#         transaction.savepoint_rollback(sid)
#         return HttpResponse('库存不足,秒杀失败')



# 乐观锁
import datetime
@transaction.atomic
def seckill(request):
    # 锁住查询到的book对象,直到事务结束
    ### 乐观锁可能会失败,我们一直尝试秒杀,直到秒成功或库存不足
    while True:
        sid = transaction.savepoint()
        book = Book.objects.filter(pk=1).first()  # 没加锁
        count = book.count
        print('现在的库存为:%s' % count)
        if book.count > 0:
            print('库存可以,下单')
            Order.objects.create(order_id=str(datetime.datetime.now()), order_name='测试订单')
            # 库存-1,扣减的时候,判断库存是不是上面查出来的库存,如果不是,就回滚
            # time.sleep(random.randint(1, 4))  # 模拟延迟
            res = Book.objects.filter(pk=1, count=count).update(count=count - 1)
            print(res)
            if res >= 1:  # 表示修改成功
                transaction.savepoint_commit(sid)
                return HttpResponse('秒杀成功')
            else:  # 修改不成功,回滚
                transaction.savepoint_rollback(sid)
                print('被别人扣减了,继续秒杀')
                continue

        else:
            transaction.savepoint_rollback(sid)
            return HttpResponse('库存不足,秒杀失败')

路由层

from django.contrib import admin
from django.urls import path
from app01.views import seckill
urlpatterns = [
    path('admin/', admin.site.urls),
    path('seckill/', seckill),
]

测试代码

import requests
from threading import Thread
def task():
    res = requests.get('http://127.0.0.1:8000/seckill/')
    print(res.text)

if __name__ == '__main__':
    for i in range(10):
        t=Thread(target=task)
        t.start()

标签:count,transaction,savepoint,乐观,book,悲观,sid,import
From: https://www.cnblogs.com/LiaJi/p/17333409.html

相关文章

  • mybatisPlus-乐观锁
    数据库中添加version字段  自定义配置类中,添加乐观锁的拦截器packagecom.atguigu.config;importcom.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;importcom.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;im......
  • 负荷需求响应模型 基于Logistic函数 采用matlab编程,考虑电价激励下的乐观响应和悲观响
    负荷需求响应模型基于Logistic函数采用matlab编程,考虑电价激励下的乐观响应和悲观响应,利用负荷需求响应模型得到峰转平、平转谷的实际负荷转移率,从而得到基于Logistic函数的负荷转移对比,程序运行稳定ID:6450676853349722......
  • MyBatisPlus——DML编程控制——乐观锁
    乐观锁业务并发现象带来的问题:秒杀最后一单用于中小型项目(2000请求以下)添加一个数据库字段,使每次请求修改数据时,这个字段就加一,当有多人同时请求时,这些人同时获取到的都是相同的该字段,但当有一人完成了秒杀后字段加一,其他同时获取到的该字段就不匹配了配置步骤数据库表中......
  • 乐观锁以及乐观锁的实现
    乐观锁介绍:乐观锁(OptimisticLocking)相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。那么我们如何实现乐观锁呢,一般来说有以下2种方式:1.使用......
  • php redis 悲观锁
     悲观锁(PessimisticLock),顾名思义,就是每次处理redis数据都以最悲观的场景展开,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是......
  • 悲观锁和乐观锁
      乐观锁实现方式:加一个标记,执行更新操作时比较标记是否相同,不相同重新读取标记然后再次更新比较或者放弃这次更新。乐观锁用到的地方不多,了解即可。     ......
  • 共享锁、排他锁、互斥锁、悲观锁、乐观锁、行锁、表锁、页面锁、不可重复读、丢失修改
    共享锁(S锁)又称为读锁,可以查看但无法修改和删除的一种数据锁。如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排它锁。获准共享锁的事务只能读数据,不能修......
  • MyBatisPlus插件扩展_OptimisticLockerInterceptor乐观锁插件的使用
    简介意图:当要更新一条记录的时候,希望这条记录没有被别人更新乐观锁实现方式:取出记录时,获取当前version更新时,带上这个version执行更新时,setversion=yourVersion+1where......
  • JPA/Hibernate:基于版本的乐观锁并发控制
    比方说,我们有一个系统由多个用户使用,其中每个实体可以被多个用户修改。我们希望避免这种情况:两个人的加载一些信息,基于他们所看到的做出一些决定,然后在相同的时间。更新状态......
  • MybatisPlus(八) 插件的使用~乐观锁插件(配置类篇)
    一、Springboot配置乐观锁插件@ConfigurationpublicclassMybatisPlusConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){......