2012-02-04 47 views
0

我試圖使用Redis的鎖定一些大的管理PostgreSQL的交易我在我的項目。 到目前爲止,我的開發環境還沒有成功。Django的,使用Redis的-PY在Django的看法鎖定

碼的一個簡單版本將看起來像:

def test_view(request): 
    connec = redis.Redis(unix_socket_path='/tmp/vgbet_redis.sock') 
    if not connec.setnx('test', ''): 
    print 'Locked' 
    else: 
    time.sleep(5) #Slow transaction 
    connec.delete('test') 
    print 'Unlocked' 
    return render_to_response("test.html") 

如果我打開該視圖的兩個翼片,所述第一一個打印5秒後解鎖,然後在10秒後未鎖定狀態的第二個打印。看起來它們是同步的,對我來說沒有任何意義。

編輯: 我試圖安裝一個Apache和一個gevent,我得到了完全相同的結果。

所以我想真的是有一些我不使用Django + Redis的理解和我的代碼是真的錯了。

任何幫助將是偉大的。

編輯2: 我剛剛通過使用redis作爲緩存與django-redis進行了嘗試。

CACHES = { 
    'default': { 
    'BACKEND': 'redis_cache.RedisCache', 
    'LOCATION': '/tmp/vgbet_redis.sock', 
    'OPTIONS': { 
     'DB': 1, 
     'PASSWORD': None, 
     'PARSER_CLASS': 'redis.connection.HiredisParser' 
    }, 
    }, 
} 

如果我在瀏覽器中打開兩個選項卡,我仍然會得到相同的結果。第二個視圖被阻塞5秒,就好像每個視圖都是同步的。

from django.core.cache import cache 
def test_view(request): 
    if cache.get('test') != None: 
    print 'Locked' 
    else: 
    cache.set('test', '', 60) 
    time.sleep(5) #Slow transaction 
    cache.delete('test') 
    return render_to_response("test.html") 

如果我打開兩個終端,在redis中我沒有讀寫的問題。所以我真的不明白爲什麼我無法在視圖中使用緩存。

+0

應該指出:你在那裏的鎖不會是原子的。最好使用[setnx](http://redis.io/commands/setnx),它可以防止競爭條件。 – 2012-02-05 07:58:21

+0

我更新了我的代碼,謝謝。 – Ashe 2012-02-05 09:54:17

回答

0

的主要原因是我的問題,是因爲我使用我的瀏覽器兩個選項卡。如果我使用兩個瀏覽器或兩個不同的IP,我的代碼異步工作(使用gevent和apache,不使用runserver,但這並不意外)。

我覺得有這樣的:如果一個唯一的會話請求了同樣的觀點多次,他們正在同步服務。我不知道這是由於服務器還是django。我無法在文檔中找到類似的東西。如果有人知道,我會真正有興趣瞭解最後一部分。

+0

啊,這可能是因爲您的網絡瀏覽器在任何時候都只會打開一定數量的連接到特定的服務器。你正在使用哪種瀏覽器? – 2012-02-05 17:42:31

+0

有趣的,鉻16 – Ashe 2012-02-05 19:32:44

+0

啊,奇怪。這應該允許至少兩個連接。 – 2012-02-05 22:12:54

2

幾件事情要檢查:

  • 默認的Django開發服務器是單線程的,所以只能一次處理一個請求。最簡單的測試方法是在不同的端口上運行兩次開發服務器(例如,./manage.py runserver 8080./manage.py runserver 8081)。
  • 如果您使用的是SQL數據庫的話,那可能阻塞的事務。這些是您正在使用的確切視圖嗎?或者你在模型上做什麼?
  • 您使用gevent提到的 - 是你一定要打電話from gevent import monkey; monkey.patch_all()猴補丁的一切嗎?另外,你如何用gevent運行你的服務器?
+0

我終於發現我的錯誤,我剛剛發佈了答案。 非常感謝您的回答,我喜歡使用兩個runserver的建議,並且我會明確地按照您更新gevent的建議。 – Ashe 2012-02-05 09:35:08

+0

您是否建議在每個視圖中調用redis.Redis(...)或創建一個全局?它會改變什麼嗎? – Ashe 2012-02-05 09:40:23

+0

您應該創建一個全局。 'Redis'(假設你正在使用'redis-py')保留了一個內部線程池,所以沒有理由不讓它成爲全局的,並且使它成爲全局的可能會加快速度(因爲新的TCP連接不會需要每次都建立)。 – 2012-02-05 17:41:22