全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Django ORM 中安全处理并发更新的最佳实践

在异步 telegram 机器人中使用 django orm 执行原子性扣减与累加操作时,需通过数据库级锁(如 `select_for_update`)和事务封装(`transaction.atomic`)避免竞态条件,推荐结合 `f()` 表达式实现无状态、线程/协程安全的字段更新。

Django ORM 完全适用于高并发场景下的数据一致性保障,但必须正确使用其并发控制机制。你示例中的代码存在两个关键风险点:一是 obj1.filed1 > 0 判断后到 save() 之间存在时间窗口,多请求可能同时通过判断并重复扣减;二是两次 save() 非原子操作,若中间出错会导致数据不一致。

推荐方案:事务 + select_for_update() + F() 表达式

from django.db import transaction
from django.db.models import F

async def on_button_click():
    try:
        with transaction.atomic():
            # 使用 select_for_update() 加行级写锁(需确保数据库支持,如 PostgreSQL/MySQL InnoDB)
            obj1 = Object1.objects.select_for_update().get(id=X)

            if obj1.field1 >= N:  # 注意:>= 避免扣成负数
                # 原子更新:所有计算在数据库层面完成,无需读取-修改-写入(RMW)循环
                Object1.objects.filter(id=X).update(field1=F('field1') - N)
                Object2.objects.filter(id=X2).update(field2=F('field2') + N)
            else:
                raise ValueError("Insufficient balance")
    except Object1.DoesNotExist:
        raise ValueError("Object1 not found")
    except Exception as e:
        # 日志记录 & 用户反馈
        logger.warning(f"Button click failed: {e}")
        raise

? 关键要点说明:

  • transaction.atomic() 确保整个块为数据库事务,失败则回滚;
  • select_for_update() 在 obj1 行上加排他锁,阻塞其他并发事务对该行的 SELECT ... FOR UPDATE 或 UPDATE,直到当前事务结束;
  • F() 表达式使更新脱离 Python 层计算,直接由数据库执行(如 SET field1 = field1 - N),彻底规避读-改-写竞态;
  • 锁定范围应精准:仅锁定实际参与更新的行(如 Object1.objects.select_for_update().get(id=X)),避免锁表或锁过多行影响性能;
  • ⚠️ 注意:select_for_update() 在 SQLite 中不生效,在 MySQL 中需启用 READ-COMMITTED 或更高隔离级别,在 PostgreSQL 中默认支持;

? 异步兼容性提示:
Django 4.1+ 原生支持异步视图与 ORM 调用,但 select_for_update() 和 transaction.atomic() 目前仍要求同步上下文(即需在 sync_to_async 包装器中执行)。Pyrogram 的异步 handler 中应这样调用:

from asgiref.sync import sync_to_async

# 在 async handler 中:
await sync_to_async(on_button_click_sync)()  # 其中 on_button_click_sync 是上述同步事务函数

? 替代思路(进阶):
若业务逻辑更复杂(如需校验多个条件、触发事件链),可考虑使用数据库原生 UPDATE ... RETURNING(PostgreSQL)或乐观锁(添加 version 字段 + WHERE version = old_version 条件更新),但对绝大多数余额类场景,atomic + select_for_update + F() 组合已足够健壮、简洁且可维护。


# mysql  # python  # go  # ai  # django 


相关文章: 昆明网站制作哪家好,昆明公租房申请网上登录入口?  ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?  建站之星后台管理:高效配置与模板优化提升用户体验  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  如何在局域网内绑定自建网站域名?  建站之星伪静态规则如何正确配置?  建站之家VIP精选网站模板与SEO优化教程整合指南  成都网站制作公司哪家好,四川省职工服务网是做什么用?  网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?  浅析上传头像示例及其注意事项  济南网站建设制作公司,室内设计网站一般都有哪些功能?  c# await 一个已经完成的Task会发生什么  长沙做网站要多少钱,长沙国安网络怎么样?  如何零成本快速生成个人自助网站?  如何快速搭建二级域名独立网站?  武汉网站如何制作,黄黄高铁武穴北站途经哪些村庄?  太平洋网站制作公司,网络用语太平洋是什么意思?  网站建设设计制作营销公司南阳,如何策划设计和建设网站?  如何通过网站建站时间优化SEO与用户体验?  设计网站制作公司有哪些,制作网页教程?  无锡营销型网站制作公司,无锡网选车牌流程?  建站主机如何安装配置?新手必看操作指南  如何通过虚拟主机快速完成网站搭建?  建站之星×万网:智能建站系统+自助建站平台一键生成  建站之星后台密码遗忘如何找回?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  如何在企业微信快速生成手机电脑官网?  高性价比服务器租赁——企业级配置与24小时运维服务  上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?  黑客如何利用漏洞与弱口令入侵网站服务器?  网站制作话术技巧,网站推广做的好怎么话术?  较简单的网站制作软件有哪些,手机版网页制作用什么软件?  制作网站外包平台,自动化接单网站有哪些?  网站制作免费,什么网站能看正片电影?  Java解压缩zip - 解压缩多个文件或文件夹实例  如何在服务器上三步完成建站并提升流量?  建站之星ASP如何实现CMS高效搭建与安全管理?  如何解决ASP生成WAP建站中文乱码问题?  如何快速使用云服务器搭建个人网站?  内部网站制作流程,如何建立公司内部网站?  建站之星后台搭建步骤解析:模板选择与产品管理实操指南  如何基于PHP生成高效IDC网络公司建站源码?  建站之星如何快速解决建站难题?  东莞专业制作网站的公司,东莞大学生网的网址是什么?  如何有效防御Web建站篡改攻击?  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  实例解析Array和String方法  建站之星官网登录失败?如何快速解决?  如何选择CMS系统实现快速建站与SEO优化?  网站制作企业,网站的banner和导航栏是指什么? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。