2010-04-08 35 views
2

我的User我想創建並存儲在數據存儲中的對象有一個email和一個username。在創建User對象時,如何確保另一個User對象不具有相同的email或相同的usernameGoogle App Engine - 處理存儲對象的併發問題

如果我只是查詢是否有其他用戶已經使用過用戶名或電子郵件,那麼可能會出現競爭狀態。

更新: 我目前正在考慮的解決方案是使用MemCache來實現鎖定機制。在嘗試將User對象存儲在數據存儲中之前,我會獲取2個鎖。首先鎖定基於email鎖定,然後鎖定基於username

由於創建新的User對象僅在用戶註冊時發生,而且更罕見的是兩個人嘗試使用相同的用戶名或相同的電子郵件,我認爲可以採用鎖定的性能命中。

我想使用的內存緩存鎖定代碼,這裏的:http://appengine-cookbook.appspot.com/recipe/mutex-using-memcache-api/

你們有什麼覺得?

回答

2

嘗試使用他們的電子郵件將您的用戶存儲爲key_name。這可以在一個簡單的步驟來完成:

MyUser.get_or_insert(email) 

讓您的MyUser通過電子郵件也很容易:

MyUser.get_by_key_name(email) 

看到這個類似的問題:add properties to users google app engine

這樣解決的兩個問題用戶使用同一封電子郵件。要對用戶名執行相同操作,請在transaction(這是get_or_insert()在幕後執行的操作)中執行「獲取具有此用戶名的用戶」查詢和「插入具有此用戶名的用戶」。

您可以通過TransactionFailedError找到另一個用戶在您的交易過程中「取得」該用戶名的情況。

絕對不想使用內存緩存互斥,因爲這while循環等待鎖釋放可以花很多的內存緩存API調用配額。

+0

你相信我能「這個用戶名讓用戶」進行查詢和「插入用戶使用該用戶名」在同一筆交易中?每個交易只能對一個實體組進行操作。做一個查詢你必須有一個祖先過濾器。 http://code.google.com/appengine/docs/python/datastore/transactions.html#What_Can_Be_Done_In_a_Transaction – Kyle 2010-04-08 22:03:21

+0

您可以查詢MyUsers並在交易中插入MyUser,您無法查詢OtherThings並將MyUser插入交易。可能有點棘手的是,我不知道你是否可以在事務內部執行'get_or_insert()',因爲它本身就是一個事務。在這種情況下,您需要在插入MyUser之前查詢用戶名和電子郵件的可用性。 – 2010-04-08 22:09:47

+0

我爲查詢放置的祖先過濾器是什麼?我的'User'對象都沒有共同的祖先。使所有的'用戶'對象具有共同的祖先並使它們在同一個實體組中是不好的。 – Kyle 2010-04-08 22:15:15

1

如果使用數據存儲的JPA IMPL,你只需要設置註釋

@Column(唯一= TRUE) 場場

這樣的數據庫將拒絕您的插入/更新..我想它是由gdatastore實現的,在這種特定情況下給用戶提供「技術錯誤」對我來說不是一件大事......但無論如何,你可以捕捉到違反約束的例外。我猜JDO也有這個。

但實際上,如果找你使用Python或Java我甚至不知道......

在Java中,據我知道你可以做交易的選擇的請求......

關於交易你也應該檢查什麼是事務隔離級別和它是如何工作在GAE ...