Django缓存导致数据库重复键错误?
可能重复的问题:
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呢?