有沒有好辦法做到這一點安全與RethinkDB。這已在issue on github中討論過,並且與獨特的二級索引有關,並且保證了自動性。實質上你必須做兩個操作。首先搜索電話號碼是否已經存在,然後添加記錄,如果不是。
即使對非分片表,RethinkDB也不支持唯一的二級索引。 (來源:Using secondary indexes in RethinkDB)
所以我們有一個種族條件。兩個請求可以在同一時間運行,既回到電話號碼不存在,然後最終插入新的記錄。下面不安全代碼將做到這一點:
new_record = {"name": "john smith", "Age": 30, "phone_number": "556"}
filter_predicate = {"phone_number": new_record["phone_number"]}
test = r.table('users').filter(filter_predicate).count().eq(0)
r.branch(test, r.table('users').insert(new_record), None).run()
下面是從運行它的輸出:
In [92]: for document in r.table('users').run(): print(document)
In [93]: new_record = {"name": "john smith", "Age": 30, "phone_number": "556"}
In [94]: filter_predicate = {"phone_number": new_record["phone_number"]}
In [95]: test = r.table('users').filter(filter_predicate).count().eq(0)
In [96]: r.branch(test, r.table('users').insert(new_record), None).run()
Out[96]:
{u'deleted': 0,
u'errors': 0,
u'generated_keys': [u'2c0ffb27-cfdb-44e7-a416-4f7be5d97ea9'],
u'inserted': 1,
u'replaced': 0,
u'skipped': 0,
u'unchanged': 0}
In [97]: for document in r.table('users').run(): print document
{u'phone_number': u'556', u'Age': 30, u'id': u'2c0ffb27-cfdb-44e7-a416-4f7be5d97ea9', u'name': u'john smith'}
In [98]: r.branch(test, r.table('users').insert(new_record), None).run()
In [99]: for document in r.table('users').run(): print document
{u'phone_number': u'556', u'Age': 30, u'id': u'2c0ffb27-cfdb-44e7-a416-4f7be5d97ea9', u'name': u'john smith'}
一個變通想到的是嘗試和失敗的優雅。也就是說,我們進行初始檢查,看看文檔是否在那裏,如果不是我們添加它。然後我們必須檢查重複項。如果發現重複,請清理。我們需要某種打破平局的方式,例如在插入文件的時候(最早是勝利者)。任何期望我們的文檔具有唯一電話號碼的查詢也需要考慮到這一點。如果兩個文件具有相同的電話號碼,請按時間升序並選擇第一個。
這一直工作得很好,謝謝 – enovacreations