2011-02-26 17 views
4

我正在運行Debian和Python 2.7.1的Web服務器上使用ZODB 3.10.2。似乎每次我嘗試從2個不同的進程訪問同一個數據庫時,我都會遇到一個神祕的異常。我試圖從一個交互式的Python會話訪問數據庫一切似乎很好地工作:ZODB中的zc.lockfile.LockError

>>> import ZODB 
>>> from ZODB.FileStorage import FileStorage 
>>> storage = FileStorage("test.db") 
>>> 

但後來我試過同一系列在同一時間運行從另一個會話的命令,它似乎並沒有工作:

>>> import ZODB 
>>> from ZODB.FileStorage import FileStorage 
>>> storage = FileStorage("test.db") 
    No handlers could be found for logger "zc.lockfile" 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/site-packages/ZODB3-3.10.2-py2.7-linux-x86_64.egg/ZODB/FileStorage/FileStorage.py", line 125, in __init__ 
    self._lock_file = LockFile(file_name + '.lock') 
    File "/usr/local/lib/python2.7/site-packages/zc.lockfile-1.0.0-py2.7.egg/zc/lockfile/__init__.py", line 76, in __init__ 
    _lock_file(fp) 
    File "/usr/local/lib/python2.7/site-packages/zc.lockfile-1.0.0-py2.7.egg/zc/lockfile/__init__.py", line 59, in _lock_file 
    raise LockError("Couldn't lock %r" % file.name) 
zc.lockfile.LockError: Couldn't lock 'test.db.lock' 
>>> 

這是爲什麼發生?可以做些什麼呢?

+0

感謝您的回答。我不知道ZODB不支持多進程訪問。我正在尋找像擱置的東西,但具有更好的併發支持。我希望能夠從一個進程可靠地寫入數據庫,同時從另一個進程讀取數據庫。我可以嘗試ZEO,或者我可以看看其他地方。 – 2011-02-27 00:54:11

回答

11

ZODB不支持多進程訪問。這就是爲什麼你得到鎖定錯誤; ZODB文件存儲已被一個進程鎖定,以防止其他進程改變它。

有幾種解決方法。最簡單的選擇是使用ZEO。 ZEO擴展ZODB機械提供通過網絡訪問的對象,你可以輕鬆地配置您的ZODB訪問ZEO服務器,而不是本地FileStorage文件:

<zodb> 
    <zeoclient> 
    server localhost:9100 
    </zeoclient> 
</zodb> 

另一種選擇是使用RelStorage,它存儲關係數據庫中的ZODB數據。 RelStorage支持PostgreSQL,Oracle和MySQL後端。 RelStorage負責處理來自不同ZODB客戶端的併發訪問。這裏是一個配置示例:

<zodb> 
    <relstorage> 
    <postgresql> 
     # The dsn is optional, as are each of the parameters in the dsn. 
     dsn dbname='zodb' user='username' host='localhost' password='pass' 
    </postgresql> 
    </relstorage> 
</zodb> 

RelStorage需要更多的前期安裝工作,但在許多情況下可以超越ZEO。

3

您不能同時從兩個進程訪問相同的數據庫文件(這很明顯)。這就是爲什麼你會得到這個錯誤。如果您需要對來自兩個或更多進程的相同data.fs文件執行操作:請使用ZEO。

+0

>(這是顯而易見的) 'sqlite'支持這個(雖然有一個巨大的鎖) – 2016-07-06 20:49:32