Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Jak mogę automatycznie odblokować stoły w Oracle po określonym czasie?

Po pierwsze, zablokowanie tabeli nie uniemożliwi innej sesji wywołania SELECT oświadczenia w stosunku do danych.

W sesji 1, jeśli zablokuję stół

SQL> lock table foo in exclusive mode;

Table(s) Locked.

Następnie mogę rozpocząć sesję 2 i przeszukiwać wszystkie dane, które chcę

SQL> select * from foo;

      COL1
----------
         1
         1

W Oracle autorzy nie blokują czytników, więc nigdy nie można uniemożliwić innej sesji wykonywania zapytań o dane w tabeli.

Wygląda na to, że to, co próbujesz zaimplementować, to pesymistyczne blokowanie. W takim przypadku zamiast blokować tabelę, wykonujesz SELECT FOR UPDATE który blokuje konkretny wpis, który zamierzasz przetworzyć. Tak długo, jak wszystkie inne sesje również próbują wykonać SELECT FOR UPDATE (w zależności od wersji Oracle, potencjalnie dodanie SKIP LOCKED kwalifikator i/lub WAIT kwalifikator). To blokuje konkretny wiersz, który przetwarzasz, i pozwala drugiej sesji albo wybrać inny wiersz lub przekroczyć limit czasu, albo stwierdzić, że nie ma wierszy do przetworzenia w zależności od specyfiki implementacji. To nie wiąże się z blokowaniem stołu.

Jedynym sposobem na zwolnienie blokady jest zwolnienie sesji, która ją nabyła (na ogół poprzez zakończenie transakcji) lub zakończenie sesji, która ją nabyła. Jeśli aplikacja kliencka nadal działa, ale nie robi nic, aby zwolnić blokadę lub zakończyć sesję, blokada zostanie wstrzymana. Administrator DBA musiałby jawnie zabić sesję, pozwalając na cofnięcie transakcji i zwolnienie blokady, aby system mógł się ponownie poruszać. Jeśli aplikacja kliencka przestaje działać lub przynajmniej przestaje odpowiadać (nadal nie wiem dokładnie, jaki scenariusz awarii omawiasz), możliwe jest, że włączenie wykrywania martwych połączeń (DCD) za pomocą Parametr „SQLNET.EXPIRE_TIME” na poziomie bazy danych spowodowałoby to, że baza danych określiłaby, że klient nie odpowiada i automatycznie zabije sesję, cofając transakcję i zwalniając blokadę.

Jeśli jednak istnieje wiele sesji przetwarzających dane, ogólnie preferowane jest użycie jakiejś formy optymistycznego blokowania. W przeciwnym razie projektujesz system, który nieuchronnie będzie wymagał od administratora danych pilnego znajdowania i zabijania sesji w celu przywrócenia użytkownikom biznesowym pracy, a to będzie wymagało coraz większej interwencji, im bardziej jest zajęty. Nie jest to coś, co lubią robić administratorzy baz danych i nie jest to coś, na co użytkownicy biznesowi lubią narzekać. Prosty, optymistyczny schemat blokowania wyglądałby jak

  • Wybierz klucz do przetworzenia i jakąś datę wskazującą ostatnią aktualizację wiersza.
  • Zaktualizuj kolumnę stanu na „przetwarzanie”, aby inne sesje nie próbowały przetworzyć tego samego wiersza.
  • Przetwórz wpis w swojej aplikacji
  • Po zakończeniu przetwarzania zaktualizuj dane, używając klucza i czasu wybranego w pierwszym kroku. Jeśli zaktualizujesz 1 wiersz, wiesz, że żadna inna sesja nie zmodyfikowała danych od momentu ich wybrania. Jeśli zaktualizujesz 0 wierszy, wiesz, że inna sesja zmodyfikowała dane od czasu ich wybrania.

Przy tego rodzaju architekturze stosunkowo łatwo jest wysłać zapytanie do bazy danych, aby zobaczyć, jakie wiersze są przetwarzane i na przykład uzyskać zadanie, które ustawia kolumnę stanu z powrotem na „nieprzetworzone” po pewnym czasie, jeśli klient tego nie zrobił skończone. W przypadku innych sesji bardzo łatwo jest wybrać inny wiersz do przetworzenia. I jest to stosunkowo bezpieczne, jeśli na przykład aplikacja zawiesza się na kilka godzin, a następnie odzyskuje, ponieważ po zakończeniu przetwarzania stwierdza, że ​​inna sesja już ponownie przetworzyła wiersz.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Próbuję zbudować statyczny plik wykonywalny CGO z bibliotekami Oracle na Linux/Ubuntu

  2. Wyzwalaj alternatywy dla dwóch tabel, które muszą się wzajemnie aktualizować

  3. Czy Oracle pobiera wszystkie wiersze przed oceną rownum?

  4. Podziel wartości oddzielone przecinkami w kolumnie w wierszu za pomocą zapytania Oracle SQL

  5. Policz liczbę wartości na identyfikator