Django中使用MySQLdb时的MySQL缓存问题

2 投票
1 回答
1228 浏览
提问于 2025-04-15 12:02

我在Python中使用MySQL和MySQLdb模块,搭配Django框架。

在这种情况下,我是以自动提交模式运行的(而且Django的transaction.is_managed()实际上返回的是False)。

我有几个进程在和数据库进行交互。

一个进程通过Task.objects.all()获取所有的Task模型。

然后另一个进程添加了一个Task模型(我可以在数据库管理工具中看到它)。

如果我在第一个进程中调用Task.objects.all(),我什么都看不到。但是如果我先调用connection._commit(),再调用Task.objects.all(),我就能看到新添加的Task。

我的问题是:在连接层面上是否涉及到缓存?这种情况正常吗(我觉得不太正常)?

1 个回答

1

这看起来确实和自动提交/表锁定有关。

如果mysqldb实现了dbapi2规范,它可能会让一个连接一直处于一个持续的事务中。当你说:'以自动提交模式运行'时,你是指MySQL本身,还是mysqldb模块?或者是Django?

不间歇性地提交完美解释了你遇到的行为:

i) 在mysqldb中,一个连接被实现为一个单一的事务(默认情况下,可能是这样)

ii) 不是在需要时才打开/关闭连接,而是(重新)使用一个(或多个)持久的数据库连接(我猜,这可能是Django架构的遗传特性)。

iii) 你的查询('读取')会在一个表上造成一个'简单读取锁'(这意味着其他连接仍然可以'读取'这个表,但想要'写数据'的连接不能(立即)写,因为这个锁阻止它们获得一个'独占锁'(写入时需要的)在这个表上。因此,写入会被无限期推迟(直到它能获得一个(短暂的)独占锁来写入——当你关闭连接或手动提交时)。

在你的情况下,我会这样做:

  • 找出在上述场景中你的数据库上有哪些表锁定
  • 在这里阅读关于Django和事务的内容。快速浏览一下,似乎使用标准的Django功能会隐式导致提交。这意味着手动编写的SQL可能不会(插入、更新……)。

撰写回答