저는 웹 서비스를 통해 수정 될 객체의 영구 저장소로 ZODB를 사용하고 있습니다. 다음은 문제를 줄인 예입니다. increment-function은 여러 스레드에서 호출되는 함수입니다. 내 문제는 두 개의 스레드에서 서로 다른 키에 대해 increment가 동시에 호출 될 때 충돌 오류가 발생한다는 것입니다.ZODB에서 다른 키를 동시에 수정하십시오.
적어도 다른 키가 수정 된 적절한 방법으로이 문제를 해결할 수 있어야한다고 생각합니까? 그렇다면, 나는 ...합니다 (ZODB-문서는 다소 다른 사이트에서 확산 될 것으로 보인다 : /) 방법에 대한 예를 찾을 관리하지 않았다 ... 어떤 아이디어에 대해 다행
을
import time
import transaction
from ZODB.FileStorage import FileStorage
from ZODB.DB import DB
from ZODB.POSException import ConflictError
def test_db():
store = FileStorage('zodb_storage.fs')
return DB(store)
db_test = test_db()
# app here is a flask-app
@app.route('/increment/<string:key>')
def increment(key):
'''increment the value of a certain key'''
# open connection
conn = db_test.open()
# get the current value:
root = conn.root()
val = root.get(key,0)
# calculate new value
# in the real application this might take some seconds
time.sleep(0.1)
root[key] = val + 1
try:
transaction.commit()
return '%s = %g' % (key, val)
except ConflictError:
transaction.abort()
return 'ConflictError :-('
이 카운터의 충돌 해결이되지 않을해야'[ '_ 횟수'] 저장 + = 새 [ '_ 횟수'] - 옛 [ '_ 횟수']'있도록 increment()가 두 번 이상 호출되는 경우를 처리 할 수 있습니까? – Duncan
@Duncan : hrm, true. 실제로, 그게 바로'BTree.Length'가하는 일입니다. 제가 갱신 할 것입니다. –
실제로, 제 문제는 병렬로 두 개의 다른 키를 변경하는 것에 관한 것이 었습니다. 예를 들어 두 개의 카운터 인스턴스가 있습니다. 이것은 "root"에 일반 숫자를 쓰는 대신 Counter 클래스를 도입하여 해결되었습니다. 사실, (mutabl) 루트가 실제로 변경되지 않는다는 사실 때문에 어느 것입니까? – sebastian