python - 在 Django ORM 中避免 MySQL 死锁

标签 python mysql django deadlock

在 MySQL 数据库上使用 Django 时出现以下错误:

OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting transaction')

错误出现在以下代码中:

start_time = 1422086855
end_time = 1422088657
self.model.objects.filter(
    user=self.user,
    timestamp__gte=start_time,
    timestamp__lte=end_time).delete()

for sample in samples:
    o = self.model(user=self.user)
    o.timestamp = sample.timestamp
    ...
    o.save()

我有几个并行进程在同一个数据库上工作,有时它们可​​能有相同的工作或样本数据重叠。这就是为什么我需要清除数据库然后存储新样本的原因,因为我不想要任何重复项。

我在事务 block 中运行整个过程 with transaction.commit_on_success() 并且经常收到 OperationalError 异常。我更希望事务不会以死锁结束,而只是锁定并等待其他进程完成其工作。

根据我的阅读,我应该正确地订购锁,但我不确定如何在 Django 中执行此操作。

确保我不会收到此错误同时仍确保我不会丢失任何数据的最简单方法是什么?

最佳答案

使用 select_for_update()方法:

samples = self.model.objects.select_for_update().filter(
                          user=self.user,
                          timestamp__gte=start_time,
                          timestamp__lte=end_time)


for sample in samples:
    # do something with a sample
    sample.save()

请注意,您不应删除选定的样本并创建新样本。只需更新过滤的记录。这些记录的锁定将被释放,然后您的事务将被提交。

顺便说一句,您可以使用 __range 来代替 __gte/__lte 查找:

samples = self.model.objects.select_for_update().filter(
                          user=self.user,
                          timestamp__range=(start_time, end_time))

关于python - 在 Django ORM 中避免 MySQL 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28191146/

相关文章:

mysql - 左连接的 SQL 替代方案

python - 使用 Django 构建金融应用程序

Python 内联增加多个变量

python - 获取 Errno 9 : Bad file descriptor in python socket

PHP文件不会复制

django - 从 django 上的关系注释列字段

django - 如何在 Django 中使用连接查询?

javascript - Scrapy tbody 标签返回一个空答案但里面有文本

python - 如何将网页中的 JSON 转换为 Python 脚本

php - MYSQL:使用 DAYNAME() 获取距今天最近的日期的数据