2008-10-27 8 views
12

Mam aplikację internetową w pracy, która jest podobna do systemu obsługi biletów. Niektórzy użytkownicy wprowadzają nowe problemy. Inni pracownicy wybierają i rozwiązują problemy. Wszystkie dane są przechowywane w serwerze MS SQL 2005.Uniemożliwianie użytkownikom pracy z tym samym rzędem

Użytkownikom roboczych do rozwiązywania problemów przejść do strony, gdzie mogą zobaczyć otwartych kwestii. Ponieważ na tej stronie może jednocześnie znajdować się do dwudziestu osób, jednym z potencjalnych problemów, które musiałem rozwiązać, było to, co dzieje się, gdy ktoś wybrał problem, który ktoś wybrał tuż po załadowaniu strony.

Aby rozwiązać ten problem, zrobiłem dwie rzeczy. Po pierwsze, widok siatki wyświetlający problemy do wybrania używa licznika AJAX do aktualizacji co sekundę. Po wybraniu problemu znika on najwyżej jedną sekundę. W przypadku wybrania jednego w ciągu sekundy otrzymają komunikat z prośbą o wybranie innego.

Problemem jest to, że AJAX częścią tego jest wysyłanie zbyt wielu nowości (to co ja zakładając), który wpływa na działanie strony i bazy danych. Ponadto aktualizacje nie są wykonywane co sekundę. Uważam, że licznik czasu nie jest wiarygodny podczas pracy w celu wyzwolenia procedur przechowywanych.

Musi istnieć lepszy sposób, ale nie mogę go znaleźć. Czy ktoś ma doświadczenie w takiej sytuacji lub ma sugestie, aby wielu użytkowników nie wybrało tego samego rekordu do zachowania? Naprawdę nie chcę całkowicie wyłączać części AJAX, ponieważ sama wiadomość sprawi, że aplikacja będzie frustrująca w użyciu.

Dzięki,

Odpowiedz

3

Dwie rzeczy mogą pomóc złagodzić twój problem.

Po pierwsze, powiadomienie po selekcji, że sprawa została podjęta, jest potrzebne niezależnie od ram czasowych aktualizacji ajax.Nawet sprawdzanie co sekundę nie oznacza, że ​​dwie osoby nie mogą kliknąć tego samego przypadku na to, co postrzegają w tym samym czasie. W takich przypadkach jeden z użytkowników musi zostać powiadomiony, że ich wybór jest nieważny, mimo że wydawał się ważny, gdy został wybrany. Powiadomienie to nie musi być skomplikowane; utrzymywanie lekkiego, pomocnego dźwięku może poprawić postrzeganie użytkownika nawet w świetle rozczarowania. Jeśli zidentyfikujesz użytkownika, który już wybrał ten rekord, nie tylko pomoże to koordynować użytkowników w przyszłości, ale także odwróci uwagę od Twojego programu na użytkownika, który wiózł soczysty przypadek. (Rzeczywiście, zarządzanie może podobnie jak dawać użytkownikom sporadyczne kolizje, ponieważ zmotywuje ich do szybszego wybierania skrzynek).

Po drugie, niewielka modyfikacja sposobu wyświetlania skrzynek może zmniejszyć liczbę kolizji. Dodanie losowego elementu do wyświetlania porządku i/lub odfiltrowanie każdego innego wyświetlanego przypadku pomoże użytkownikom wybrać różne przypadki w sposób naturalny. Rozpoznawanie ludzkiego wzorca i wybór zadania nie są przypadkowe, więc niewielkie zmiany w prezentacji mogą równać się dużym zmianom w zachowaniu selekcji. Zmniejszenie szansy na kolizję powoduje, że powiadomienia o kolizjach rzadko (a przez to mniej frustrujące dla użytkowników). Jest to nawet lepsze, jeśli twoi użytkownicy mogą zostać podzieleni na klasyfikacje, które mogą pomóc w określeniu przydatnego porządkowania/filtrowania spraw.

Dobra, trzecią rzeczą, która pomoże ci z czasem, jest zachowanie logu o zdarzeniach (z przydatnymi meta danymi o kolizji —, takimi jak kto był zaangażowany i czas selekcji). Uzbrojone w solidne dane kolizyjne, możesz znaleźć to, co działa, a co nie. Z biegiem czasu możesz udoskonalić swoją aplikację do rzeczywistych przypadków użycia, a także wcześnie wykryć potencjalne problemy. Nic nie uspokaja użytkowników bardziej niż bycie na wierzchu problemu (i jest w stanie wyjaśnić swoje plany, aby rozwiązać ten problem), zanim jeszcze zdadzą sobie sprawę, że istnieje.

Dzięki tym łagodzącym wzorcom prawdopodobnie okaże się, że można bezpiecznie zmniejszyć czas kwerendy ajaxowej bez wpływu na wygodę użytkownika. A dzięki przydatnemu protokołowaniu uzyskasz pewność, że wszelkie wprowadzone przez ciebie poprawki działają (lub nie są jeszcze bardziej przydatne).

+0

+1 dla randomizacji, dokładnie to, co zamierzałem zasugerować! –

+1

Losowa kolejność nie będzie działać. Bilety mają priorytet ważności po wygaśnięciu poziomu usług. –

+1

Jakie są podstawy wygaśnięcia poziomu usług? Czy to jest ustalenie oparte na czasie? W zależności od Twojego problemu, możesz je pogrupować w ciągu najbliższej minuty (lub piętnastu minut) i mieć "wystarczająco dobre". W każdym razie wiem, że prośba o wyjątek od priorytetów jest politycznie problematyczna, ale jeśli * możesz *, może się to opłacać. –

2

Czy próbowałeś zwiększyć czas między odświeżeniami. Spodziewam się, że raz na 30 sekund będzie wystarczające. 40 żądań/minutę to znacznie mniej obciążenia niż 1200/minutę. Twoi użytkownicy mogą nawet nie zauważyć różnicy.

Jeśli tak, w jaki sposób o dostarczenie przycisk odświeżania na stronie więc użytkownicy mogą ręcznie odświeżyć listę tuż przed wybierając element, aby uniknąć irytujących wiadomości, jeśli zechcą.

+0

Doszedłem do wniosku, że AJAX stosowany w ten sposób nie jest dobrym rozwiązaniem - czy to co sekundę, czy co 30 sekund. Odświeżanie to dobry pomysł. Nie pomyślałem o tym. Mały link nad siatką sprawnie działałby. Mimo to traci część użyteczności. –

+0

Zazwyczaj używam odświeżania, aby powiadamiać użytkowników, gdy nowe informacje zostały dodane, gdy nie nawigowały przez jakiś czas. Chociaż częstotliwość odświeżania jest podobna do 5 minut. – tvanfosson

+0

Popraw mnie, jeśli coś przeoczyłem, ale wygląda na to, że zalecam rozwiązywanie problemu współbieżności za pomocą wywołania "sleep()" zamiast korzystania z blokady. Nie rozwiąże problemu edycji równoległej, po prostu ją zamaskuj. – asveikau

2

Jeśli to możliwe ograniczenie system tak, że po prostu dostać kolejną kwestią otwartą off kolejce pracy zamiast po nich móc wybierać spośród wszystkich otwartych kwestii.

Jeśli nie jest to możliwe, przypuszczam, że można sprawdzić na wybranym danej sprawy, aby zobaczyć, czy jest jeszcze dostępny. Jeśli nie jest dostępna, usuń ją po kliknięciu przez użytkownika. W ten sposób żądasz tylko wtedy, gdy faktycznie coś klikniesz, zamiast ciągłego odpytywania danych.

+0

Niestety, ze względu na charakter pracy, ograniczenie do następnego w kolejce nie jest opcją. Podoba mi się pomysł, aby zniknął, gdy użytkownik kliknie, jeśli został już wybrany, ale martwię się, że będzie po prostu frustruć użytkowników. –

+0

Myślę, że możliwa frustracja użytkownika jest bardzo ważnym problemem. Na pewno chcesz prototypować dla akceptacji użytkownika, jeśli pójdziesz tą trasą. Myślę, że jesteś zdecydowanie w ciasnym miejscu ze współbieżnością a użytecznością. –

+0

Dziękujemy za opinię. Wiesz, kiedy po raz pierwszy zacząłem pracować z AJAX, pomyślałem: "W końcu umożliwi to wszystkim użytkownikom synchronizację z danymi". Nie jestem do końca rozczarowany, ale na pewno wybiórczo zapomniałem, jak wpłynie na mnie wydajność. –

4

Umieść pole czasowe blokady w rzędzie w bazie danych. Napisz przechowywany proc, który zwraca wartość true lub false, jeśli timest z expiration jest starszy niż konkretny czas. Ustaw sesje w aplikacji internetowej, aby wygasły w tym samym czasie, minutę lub dwie. Gdy użytkownik wybierze wiersz, trafi do przechowywanego proc, który pomaga aplikacji zdecydować, czy powinna pozwolić użytkownikowi na jej modyfikację.

Nadzieja, że ​​sens ....

+0

Nie mam zbyt dużego doświadczenia z twoją metodą, ale myślę, że ją rozumiem. Czy użytkownicy mogliby następnie próbować modyfikować rekordy, które zostały już wybrane? Naprawdę chciałbym, jeśli to możliwe, powstrzymać ich od kłopotów z wyborem niedostępnych rekordów. –

+0

Cóż, jak możesz je ukryć, jeśli nie było oddzwonienia do serwera? –

+0

ajax za pomocą jakiegoś jquery baby – craigmoliver

3

Zrobiłem coś podobnego, gdzie kiedyś użytkownik otworzy biletów (wiersz) jest przypisany ten bilet do tego użytkownika i ustawić wartość na tej płycie, jak i FK temu konkretnego użytkownika, więc gdyby ktoś próbował otworzyć ten bilet (wiersz), dałby im znać, że został już przydzielony komuś innemu.

+0

To właściwie część tego, co teraz robimy. Zmieniamy kod statusu problemu, aby wskazać, że jest on utrzymywany. Ciągle aktualizujemy znacznik czasu, który utrzymuje rekord w tym stanie, o ile jest aktualizowany. Tylko to może oznaczać, że użytkownicy wybiorą rekordy, których nie mogą wykonać. –

1

Nie widzę problemu, zwłaszcza po tym, jak wspomniałeś, że już zgłaszasz bilety w toku/są utrzymywane i masz sygnaturę czasową/wersję przedmiotu.

Czy nie wystarczy następujący:

  1. użytkownik przegląda bilety i widzi listę dostępnych biletów tj Wyklucza to te, które są w db jak w toku. Jeśli chcesz, aby użytkownicy widzieli także bilety w toku, zaznacz je wyraźnie w statusie biletu i wyłącz opcję, aby je wziąć.
  2. Użytkownik albo zgłasza bilet jako w toku jawnie lub niejawnie, otwierając bilet (w zależności od doświadczenia użytkownika/sposobu jego przedstawienia użytkownikom).
  3. Użytkownik wyraźnie przesuwa bilet do innego stanu tj zakończone, nieważne, w oczekiwaniu na informacje zwrotne itd

Gdy elementy są pobierane na 1, to należą datownika/wersję. Kiedy 2 się zdarza, używasz optymistycznego podejścia do współbieżności, aby upewnić się, że jeśli 2 osoby spróbują zaktualizować bilet, to tylko pierwsza z nich zakończy się sukcesem.

Co się stanie, że dla drugiej osoby, aktualizacja ... gdzie ... timestamp = @timestamp nie znajdzie żadnych rekordów do aktualizacji, a ty zgłosisz, że bilet został już zajęty.

Jeśli chcesz, możesz zbudować na górze powyższego, aby zaktualizować interfejs w miarę przechwytywania biletów.Może to być po prostu pełne odświeżenie bieżącej strony biletów po x czasie (może powiadomienie/monitowanie użytkownika), lub nawet pobranie listy biletów zmienionych dla strony biletów wyświetlanych za pomocą ajax. Wciąż masz wcześniejsze kroki, ponieważ ta modyfikacja jest tylko wygodą dla użytkowników.

+0

Wszystko, co opisałeś, dzieje się teraz. Problem polega na tym, że aktualizacja gridview z AJAX jest nieefektywna. Jeśli ustawię licznik aktualizacji na dłuższy okres, użytkownicy zaczną wybierać ten sam rekord. Optymistyczna współbieżność utrzymuje dane w ryzach, ale marnuje czas użytkownika. Musisz wyobrazić sobie listę 300 przedmiotów posortowanych według priorytetu i do 20 użytkowników wybierających najwyższy. –