2015-12-26 47 views
0

在我看來,如果重新嘗試,使用IF會使聲明失敗。因此,該聲明不是冪等的。例如,考慮到以下CQL,如果由於超時或系統問題而失敗,並且我重試了它,那麼它可能無法工作,因爲另一個人可能在重試之間更新了版本。CQL3「IF」是否使我的更新不是冪等的?

UPDATE users 
SET name = 'foo', version = 4 
WHERE userid = 1 
IF version = 3 

Cassandra更新的最佳實踐是使更新冪等,但IF操作符與此直接相反。我錯過了什麼嗎?

回答

1

這個問題更關於線性化(排序)比我認爲冪等性。此查詢使用Paxos在應用更改之前嘗試確定系統的狀態。如果系統的狀態是相同的,那麼可以多次重試查詢而不改變結果。這與大多數Cassandra寫道的不同,這提供了一種弱的排序形式(並且代價昂貴)。通常,如果您試圖記錄系統狀態(而不是歷史記錄或日誌),則只應使用CAS操作

如果您可以提供幫助,請不要使用其中的許多查詢,指南建議只有一小部分您的查詢依賴於此行爲。

2

如果您的應用程序是冪等的,那麼通常您不需要使用昂貴的IF子句,因爲您的所有客戶端都將嘗試設置相同的值。

例如,假設您的客戶正在彙總某些值並將結果寫入彙總表。每個客戶端都會計算相同的總數並寫入相同的值,因此多個客戶端寫入該客戶端或寫入該客戶端的順序並不重要,因爲它將具有相同的值。

如果您實際所尋找的是互相排斥,例如保持銀行平衡,那麼可以使用IF子句。您可能會讀取一行以獲得當前餘額,然後減去一些資金並僅在餘額自您讀取後沒有改變時更新餘額。如果另一個客戶試圖同時添加存款,那麼它將失敗,並且將不得不再次嘗試。

但是,如果不互相排斥,另一種方法是將每個提款和存款作爲單獨的集羣交易行編寫,然後將餘額計算爲應用所有交易行的冪等結果。

您可以使用IF子句進行冪等寫入,但似乎毫無意義。第一個執行寫操作的客戶端會成功,Cassandra會返回值「applied = True」。下一個嘗試同樣寫入的客戶端將返回「applied = False,version = 4」,表示該行已經更新到版本4,因此沒有任何更改。

相關問題