我正在开发一个需要灵活搜索动态数据集的AppEngine项目,Google的Search API似乎符合要求,所以我想用它来持久化数据集。一个很大的缺陷是它没有ACID属性或事务概念,特别是在处理数据存储区的并发更改时。我想我可以通过实现存储在Memcache中的锁来解决它。
这样的事情似乎会起作用:
@ndb.transactional
def do_in_transaction(stuff):
client = memcache.Client()
# acquire lock
while True:
lock = client.gets(doc_id)
if lock == 'arbitrary payload':
time.sleep(.01)
elif client.cas(doc_id, lock='arbitrary payload')
break
try:
old_doc = index.get(doc_id)
...do stuff in the datastore...
...push new document with changes...
except:
raise ndb.Rollback
index.put(old_doc)
finally:
# release lock
client.delete(doc_id)
我不希望访问任何特定文档会特别引起争议,我认为Memcache锁定密钥的寿命很短,以至于启动它们的风险相对较低。如果它成为问题,我总是可以将锁放在数据存储区中。
我之所以提出这个问题,是因为我没有大量的网络开发或并发经验。我错过了任何竞争条件或边缘情况吗?除了显而易见的改进(例如锁定获取的退避,将其全部放在上下文管理器中)之外,是否有任何理由这不是一个好主意?