在 django 中创建原子事务是不是会自动创建锁

Posted

技术标签:

【中文标题】在 django 中创建原子事务是不是会自动创建锁【英文标题】:Does creating atomic transaction in django create a lock automatically在 django 中创建原子事务是否会自动创建锁 【发布时间】:2018-03-16 21:22:21 【问题描述】:

我在视图中的 transaction.atomic() 中有一个代码块。我的问题是 Django 是否在幕后创建了一些内置的表锁定。

with transaction.atomic():
    #code block that does database operations
    update_user() #this updates user table
    create_customer_products() #this updates user id to customer products table

原因是我在运行代码块时收到“超过锁定等待超时;尝试重新启动事务”错误。

设置是centos上的django mysql

【问题讨论】:

请描述您的环境并添加相关代码。 这是 MySQL 返回的错误。 ***.com/questions/5836623/… 是的,这是 mysql 返回的错误。这让我想知道在使用 transaction.atomic() 时 django 是否设置了锁。因为我自己并没有把桌子锁在任何地方。 为了在innodb表中修改或插入记录,事务需要在mysql中获取排他锁。如果同一条记录(或间隙)已被另一个事务锁定,则 MySQL 等待锁定被释放或发生上述超时。根据上面的代码,我们无法判断出了什么问题(如果有的话)。您可以查看 innodb 监视器以获取更多信息,但如果没有死锁,它的使用也会受到限制。 @Shadow 我得到了我想要的答案。所以 Django 原子事务确实在幕后创建了“锁”。如果您可以作为答案而不是作为评论发布,我可以接受。 【参考方案1】:

为了在innodb表中修改或插入记录,事务需要在MySQL中获取exclusive lock:

UPDATE ... WHERE ... 在搜索遇到的每条记录上设置一个排他的下一个键锁。但是,使用唯一索引锁定行以搜索唯一行的语句只需要索引记录锁。

...

INSERT 在插入的行上设置排他锁。此锁是索引记录锁,而不是 next-key 锁(即没有间隙锁),并且不会阻止其他会话插入到插入行之前的间隙中。

如果同一条记录(或间隙)已被另一个事务锁定,则 MySQL 等待锁定被释放或发生上述超时。

根据上面的代码,我们无法判断出了什么问题(如果有的话)。您可以查看innodb status monitor 以获取更多信息,但如果没有死锁,它的使用也会受到限制。

这种行为是 MySQL 固有的,应用程序的编程语言和库不能影响这一点。

【讨论】:

以上是关于在 django 中创建原子事务是不是会自动创建锁的主要内容,如果未能解决你的问题,请参考以下文章

我可以在没有自动 ID 的情况下在 Django 中创建模型吗?

如何在django创建模板中创建对象时自动插入当前用户?

Linux中创建Django项目

Django - ORM - 事务, 乐观锁, 悲观锁

如何在 Django 中创建自动递增整数字段?

ReactiveMongoDatabase:如何预先创建集合:无法在多文档事务中创建命名空间