2012-07-06 11 views
7

muszę zrobić kwerendę wewnątrz Transaction, jednak nie wiem podmiotu @Id, co mam jest wartość pola, jak nazwa użytkownika, ale nie ID,Tylko kwerendy Przodków są dozwolone wewnątrz transakcji, jak sobie z tym poradzić?

Więc innymi słowy, Nie mogę utworzyć obiektu, aby wykonać zapytanie. Jak mogę wykonać zapytanie, aby uzyskać encję wewnątrz Transaction?

+1

Jak wiesz, nie możesz tego zrobić. To wydaje się być problemem projektowym. Być może możesz spróbować zadać to pytanie według tego, co próbujesz zrobić. – sahid

Odpowiedz

14

Bez sięgnięcie do głębszych zagadnień projektowych, są naprawdę dwie opcje:

1) Uruchom kwerendę poza transakcji.

Objectify (oznaczyłeś ten post tagiem) ułatwia wykonywanie zapytań nietransakcyjnych nawet w trakcie transakcji. Po prostu uruchom nową instancję niezwiązaną z transakcją i użyj jej do uruchomienia kwerendy ... a następnie wróć do pracy w transakcji. Należy pamiętać, że to wybicie się z transakcji i może mieć wpływ na integralność operacji. Często to nie ma znaczenia.

Jeśli używasz Objectify4 można po prostu uruchomić operację takiego:

ofy.transactionless.load().type(Thing.class).filter("field", value)...etc 

2) Użyj podmiot odnośników

zwykle jest to prawidłowa odpowiedź gdy ma do czynienia z rzeczami takimi jak nazwy użytkowników. Utwórz osobny podmiot, który mapuje nazwę użytkownika do obiektu użytkownika tak:

class Username { 
    @Id String username; 
    Key<User> user; 
} 

transakcji Zastosowanie XG aby utworzyć nazwę użytkownika za każdym razem utworzyć użytkownika i zaktualizować go, jeśli pozwalają na zmianę nazwy użytkownika. Teraz, aby przeprowadzić transakcyjne wyszukiwanie Użytkownika według nazwy użytkownika, najpierw należy wyszukać Nazwę użytkownika, a następnie użyć jej do wyszukania Użytkownika.

+0

Chcę użyć String Id, jestem OK dla niego dla identyfikatora Nazwa użytkownika jednak hwen Mam String ID, który jest losowy ciąg, być może, że może wahać się od krótkich łańcuchów do bardzo długich ciągów. Widzę, że klucz Datastore'a jest "wzdrygnięty", to znaczy, klucz GAE jest proporcjonalny do długości @ID, jak sobie z tym poradzić? – xybrek

+0

To brzmi jak przedwczesna optymalizacja. Nie martwiłbym się tym, chyba że planujesz przechowywać petabajty. – stickfigure

+0

Racja, czy jednak nie obniża to wydajności do tego stopnia, że ​​zapis/odczyt wymagałby nieco więcej czasu do zatwierdzenia? Jeśli nie, wszystko w porządku. Jednak to, co martwię się o moją aplikację, będzie rozliczane jako czas obliczeniowy. Tak długi odczyt/zapis oznacza droższe? – xybrek

0

Miałem podobny problem, a najprostszą metodą, jaką wymyśliłem, jest użycie jednej dummy jednostki nadrzędnej. Zamiast korzystać z transakcji XG i wstawiania innej nazwy użytkownika dla każdej innej jednostki użytkownika, po prostu utwórz jedną dumną jednostkę nadrzędną i ustaw ją jako przodka każdej jednostki użytkownika, którą utworzysz. Myślę, że ta metoda pozwala zaoszczędzić sporo przestrzeni i problemów z zarządzaniem danymi.

+2

Wadą tego jest to, że wszystkie jednostki użytkownika kończą się w jednej grupie encji i zgodnie z dokumentacją można mieć tylko jedno pismo do grupy entived: [dokumentacja Datastore] (https://cloud.google.com/ appengine/docs/python/datastore/structuring_for_strong_consistency? csw = 1) –

+0

Nie znałem tego ograniczenia. Dziękuję za wskazanie. – kerafill

Powiązane problemy