4

DebianとPython2.7.1を実行しているWebサーバーでZODB3.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'
>>>

なぜこうなった?それについて何ができるでしょうか?

4

3 に答える 3

11

ZODBはマルチプロセスアクセスをサポートしていません。これが、ロックエラーが発生する理由です。ZODBファイルストレージは、他のプロセスがそれを変更するのを防ぐために、1つのプロセスによってロックされています。

これを回避する方法はいくつかあります。最も簡単なオプションは、ZEOを使用することです。ZEOはZODB機構を拡張して、ネットワーク経由でオブジェクトへのアクセスを提供します。ローカルのFileStorageファイルの代わりにZEOサーバーにアクセスするようにZODBを簡単に構成できます。

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

もう1つのオプションは、ZODBデータをリレーショナルデータベースに格納するRelStorageを使用することです。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を上回る可能性があります。

于 2011-02-26T18:44:07.410 に答える
3

2つのプロセスから同時に同じデータベースファイルにアクセスすることはできません(これは明らかです)。そのため、このエラーが発生します。2つ以上のプロセスから同じdata.fsファイルに対してアクションを実行する必要がある場合:ZEOを使用します。

于 2011-02-26T18:34:50.253 に答える
0
## Let the program run once (if it's already running, don't run it again)
## Run the program, open the form
import sys
import zc.lockfile
try:
    lock = zc.lockfile.LockFile('lock', content_template='{pid};{hostname}')
    if __name__ == '__main__':
        mainForm()
except zc.lockfile.LockError:
    sys.exit()

## zc.lockfile thanks
## https://pypi.org/project/zc.lockfile/#detailed-documentation
于 2021-12-18T12:37:33.860 に答える