Django缓存导致数据库重复键错误?

1 投票
1 回答
1010 浏览
提问于 2025-04-16 21:21

可能重复的问题:
Django的cache.set()导致重复键错误

我在使用Django的数据库缓存时遇到了这个问题:

ERROR:  duplicate key value violates unique constraint "cache_pkey"
STATEMENT:  INSERT INTO "cache" (cache_key, value, expires) VALUES (E':1:cms-menu_nodes_en-us_1', E'gAJdcQEoY21lbnVzLmJhc2UKTmF2aW
LOG:  server process (PID 8453) was terminated by signal 9: Killed
LOG:  terminating any other active server processes
LOG:  all server processes terminated; reinitializing
FATAL:  could not create shared memory segment: Cannot allocate memory
DETAIL:  Failed system call was shmget(key=5432001, size=29278208, 03600).

我查看了表格,果然发现有一个键为':1:cms-menu_nodes_en-us_1'的记录。我在这里找到了一个类似的问题,但我没能完全理解问题出在哪里。

有没有人有想法或建议?听起来像是Django核心的一个bug,因为如果一个键已经存在,它应该更新记录。

编辑:我应该说明一下,数据库是PostgreSQL 8.4.7。谢谢lazerscience。

编辑 @ Jack M:我还没能重现这个错误,但我认为问题出在django.core.cache.backends.db.DatabaseCache中的一个叫set()的方法里,这个方法会调用_base_set()

1 个回答

1

听起来像是Django核心的一个bug,因为如果一个键存在,它应该更新记录。

确实是这样,但我觉得这个bug可能和并发问题有关。在这种情况下,可以在应用层面解决。比如说,两个相邻的请求同时对同一个资源/页面等执行exist()检查,结果都没有找到记录,然后就开始插入新的记录——这时候没有加锁,也没有把这个操作放在一个事务里,这样就会导致问题出现(因为这只是一个缓存),然后继续执行。

这也引出了一个问题:你确定在数据库中使用缓存是正确的吗?通常情况下,数据库在一个网页应用中是个瓶颈(尤其是使用ORM的时候),而缓存的目的就是为了避免这个瓶颈。你是不是应该使用memcache呢?

撰写回答