我正在尝试在运行Debian和Python 2.7.1的Web服务器上使用ZODB 3.10.2。似乎每次我尝试从2个不同的进程访问同一个数据库时,我都会遇到一个神秘的异常。我尝试从交互式Python会话访问数据库,一切似乎都运行良好:
>>> 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 :(得分: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。
答案 1 :(得分:3)
您无法同时从两个进程访问相同的数据库文件(很明显)。这就是你得到这个错误的原因。如果需要对来自两个或多个进程的同一data.fs文件执行操作:使用ZEO。