栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Django中如何处理这种比赛情况?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Django中如何处理这种比赛情况?

基本上get_or_create 可能会失败 -如果你查看其来源,就会发现它是:get,if-problem:save + some_trickery,if-still-problem:再次获取,if-still-problem:投降并加薪。

这意味着,如果有两个同时运行的线程(或进程)同时运行

create_or_update_myobj
,都试图
get_or_create
相同的对象,则:

  • 第一个线程试图获取它-但它尚不存在,
  • 因此,线程尝试创建它,但是在创建对象之前…
  • …第二个线程试图获取它-这显然失败了
  • 现在,由于MySQLdb数据库连接的默认AUTOCOMMIT = OFF和REPEATABLE READ可序列化级别,两个线程都冻结了它们对MyObj表的视图。
  • 随后,第一个线程创建其对象并优雅地返回它,但是…
  • …第二个线程无法创建任何东西,因为它将违反
    unique
    约束
  • 有趣的是,
    get
    由于MyObj表的冻结视图,因此第二个线程的后续操作看不到在第一个线程中创建的对象

因此,如果你想安全地进行

get_or_create
任何操作,请尝试以下操作:

 @transaction.commit_on_success def my_get_or_create(...):     try:         obj = MyObj.objects.create(...)     except IntegrityError:         transaction.commit()         obj = MyObj.objects.get(...)     return obj

该问题还有第二种解决方案-使用READ COMMITED隔离级别,而不是REPEATABLE READ。但是它的测试较少(至少在MySQL中是这样),因此可能存在更多的错误/问题-但至少它允许将视图绑定到事务,而无需在中间提交。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/411146.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号