django实现悲观锁乐观锁

这篇具有很好参考价值的文章主要介绍了django实现悲观锁乐观锁。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前期准备

# 线上卖图书
	-图书表  图书名字,图书价格,库存字段
    -订单表: 订单id,订单名字
    
# 表准备
	class Book(models.Model):
        name = models.CharField(max_length=32)
        price = models.IntegerField()  #
        count = models.SmallIntegerField(verbose_name='库存')
    class Order(models.Model):
        order_id = models.CharField(max_length=64)
        order_name = models.CharField(max_length=32)
        
# 使用mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'lqz',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'USER': 'lqz',
        'PASSWORD': '123',
    }
}

# 创建lqz数据库

1.原生mysql悲观锁

begin; # 开启事务

select * from goods where id = 1 for update;  # 行锁

# order表中加数据

update goods set stock = stock - 1 where id = 1; # 更新

commit; #提交事务

2.orm实现上述(悲观锁) 

#1  使用悲观锁实现下单
@transaction.atomic  # 整个过程在一个事物中---》改两个表:book表减库存,订单表生成记录
def seckill(request):
    # 锁住查询到的book对象,直到事务结束
    sid = transaction.savepoint() # 保存点
    # 悲观锁: select_for_update()
    # 加锁了--》行锁还是表锁? 分情况,都有可能
    #
    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(random.randint(1, 4))  # 模拟延迟
        book.count=book.count-1
        book.save()
        transaction.savepoint_commit(sid)  # 提交,释放行锁
        return HttpResponse('秒杀成功')
    else:
        transaction.savepoint_rollback(sid) #回滚,释放行锁
        return HttpResponse('库存不足,秒杀失败')

3 乐观锁秒杀--》库存还有,有的人就没成功

# 2 乐观锁秒杀--普通版
@transaction.atomic
def seckill(request):
    # 锁住查询到的book对象,直到事务结束
    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)
        if res >= 1:  # 表示修改成功
            transaction.savepoint_commit(sid)
            return HttpResponse('秒杀成功')
        else:  # 修改不成功,回滚
            transaction.savepoint_rollback(sid)
            return HttpResponse('被别人改了,回滚,秒杀失败')

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

 文章来源地址https://www.toymoban.com/news/detail-653333.html

到了这里,关于django实现悲观锁乐观锁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 悲观锁和乐观锁、缓存

    悲观锁: 悲观锁的实现通常依赖于数据库提供的机制,在整个处理的过程中数据处于锁定状态,session的load方法有一个重载方法,该重载方法的第三个参数可以设置锁模式,load(object.class , int id,LockMode.?),该方法的?就是具体的锁模式。 乐观锁: 乐观锁使用版本号或者时间戳

    2024年02月09日
    浏览(34)
  • [锁]:乐观锁与悲观锁

    摘要:乐观锁;悲观锁;实现方法;本地锁;分布式锁;死锁;行级锁;表级锁 问题 : ① 在多个线程访问共享资源时,会发生线程安全问题,例如:在根据订单号生成订单时,若用户第一次由于某种原因(网络连接不稳定)请求失败,则会再次发生请求,此时便会产生同一

    2024年02月08日
    浏览(29)
  • 悲观锁和乐观锁(易懂)

    这里可以把悲观锁看作悲观的人,啥事都往最坏的方向想。乐观锁看作乐观的人,啥事都往最好的方向想。 首先,说一下悲观锁。 悲观锁就是假设并发情况下一定会有其他线程来修改数据,因此在处理数据之前,先将数据锁住,确保其他线程不能进行修改 。感觉像一个过于

    2024年02月08日
    浏览(24)
  • [锁]:乐观锁、悲观锁与死锁

    摘要:乐观锁;悲观锁;实现方法;本地锁;分布式锁;死锁;行级锁;表级锁 问题 : ① 在多个线程访问共享资源时,会发生线程安全问题,例如:在根据订单号生成订单时,若用户第一次由于某种原因(网络连接不稳定)请求失败,则会再次发生请求,此时便会产生同一

    2024年02月08日
    浏览(27)
  • 什么是乐观锁和悲观锁?

    乐观锁和悲观锁是并发控制的两种不同策略,用于在多线程环境下管理共享资源的访问。它们有不同的思想和实现方式: 悲观锁(Pessimistic Locking) : 思想 :悲观锁的思想是,它假定在并发访问中会发生冲突,因此在访问共享资源之前会先加锁,以防止其他线程访问。悲观

    2024年02月10日
    浏览(25)
  • MySQL乐观锁与悲观锁

    遇见并发情况,需要保证数据的准确性,也就是与正确的预期一致,此时就会用到锁。 锁是在并发下控制程序的执行逻辑,以此来保证数据按照预期变动。 如果不加锁,并发情况下的可能数据不一致的情况,这是个概率问题。 乐观锁很乐观,假设数据一般情况不会造成冲突

    2024年01月23日
    浏览(26)
  • mybatis使用乐观锁和悲观锁

    悲观锁和乐观锁的概念: 悲观锁:就是独占锁,不管读写都上锁了。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。 乐观锁:不上锁,读取的时候

    2024年02月10日
    浏览(28)
  • redis实战---乐观锁与悲观锁

    最近一直在研究Redis,今天学习到了乐观锁与悲观锁的部分,在这里进行总结。 Redis是一个内存中的键值存储系统,支持多种数据结构,如字符串、哈希、列表等。 Redis提供了两种锁机制,即乐观锁和悲观锁。 乐观锁是一种乐观的并发控制策略,它认为数据在大多数情况下

    2023年04月09日
    浏览(29)
  • (学习笔记-进程管理)什么是悲观锁、乐观锁?

    最底层的两种就是 [互斥锁和自旋锁],有很多高级的锁都是基于它们实现的。可以认为它们是各种锁的地基,所以我们必须清楚它们之间的区别和应用。 加锁的目的就是保证共享资源在任意时间内,只有一个线程访问,这样就可以避免多线程导致共享数据错乱的问题。 当已

    2024年02月11日
    浏览(29)
  • Redis:事务操作以及监控(悲观锁,乐观锁)

    事务操作是指:在一组操作中,有很多的命令,如果在这组操作时,有一个命令出现的了bug,那么这组这组操作会进行回滚,将环境还原成没有开始这组操作时的状态。在MySQL等关系型数据库中事务操作可能会出现这种结果,但是在redis则也可能出现其他的错误,那就是语法问

    2024年02月05日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包