Przewodnik dla programistów ostrzega, że utrzymywanie otwartej transakcji bazy danych przez cały czas trwania czatu opartego na AI może prowadzić do błędnych odpowiedzi i paraliżować system zarządzania bazą danych (DBMS). Uwaga, skierowana do zespołów budujących narzędzia oparte na LLM, mówi, że takiej praktyki „nie powinno się stosować” i proponuje w zamian cztery krótkotrwałe wzorce zapewniania spójności.

Dlaczego to ostrzeżenie jest ważne

Asystenci napędzani przez LLM często zadają serię pytań uzupełniających: odczytują rekord, proszą o szczegół, a następnie pytają o sumę. Jeśli dane źródłowe zmienią się między tymi krokami, asystent może zwrócić sprzeczne wyniki – jedna z odpowiedzi będzie błędna. Kuszącym rozwiązaniem wydaje się otwarcie pojedynczej transakcji na początku rozmowy i utrzymywanie jej do zakończenia czatu. W praktyce takie podejście blokuje wersje wierszy, zapełnia tempdb, utrzymuje blokady i zakłóca mechanizm puli połączeń (connection pooling).

Co prowadzi do długotrwałych transakcji

  • Wieloturowe promptowanie (Multi-turn prompting) – modele LLM zazwyczaj generują kilka promptów, zanim użytkownik zobaczy odpowiedź.
  • Wywołania narzędzi (Tool calls) komunikujące się z bazą danych – każda tura może wywoływać procedurę składowaną, polecenie SELECT lub UPDATE.
  • Niekontrolowany zakres transakcji – programiści czasem obejmują całą rozmowę blokiem BEGIN…COMMIT, zakładając, że zagwarantuje to spójność danych.

Gdy czat się przedłuża, silnik bazy danych musi zachować oryginalne wersje wierszy, aby transakcja widziała stabilny widok danych. Wersje te zajmują miejsce w tempdb, zużywając przestrzeń i operacje wejścia/wyjścia (I/O). Blokady utrzymywane przez ten sam czas blokują równoległe operacje zapisu, a bezczynne połączenie może wyczerpać pulę, zmuszając nowych użytkowników do oczekiwania na wolne miejsce.

Cztery krótkotrwałe wzorce

Przewodnik zaleca traktowanie spójności jako kwestię dotyczącą pojedynczego wywołania narzędzia, a nie całej rozmowy. Cztery wzorce to:

  1. Instrukcje na żywo (Live statements) – każde wywołanie działa na domyślnym poziomie izolacji, widząc tylko dane, które zostały zatwierdzone (committed) w momencie wykonania. Jest to najprostszy model; wywołujący akceptuje fakt, że dane mogą ulec zmianie od poprzedniej tury.
  2. Transakcje ograniczone (Bounded transactions) – programista grupuje kilka instrukcji w ramach pojedynczej, krótkiej transakcji, która kończy się przed kolejną turą LLM. Gwarantuje to atomowość tej partii danych bez przeciągania transakcji poza wywołanie narzędzia.
  3. Odczyty migawkowe (Snapshot reads) – operacja rozpoczyna się od zdefiniowanej sygnatury czasowej migawki (snapshot timestamp), co zapewnia stabilny widok bazy danych przez czas trwania wywołania. Wszystkie odczyty w ramach wywołania widzą te same dane, nawet jeśli występują równoległe zapisy.
  4. Raporty zmaterializowane (Materialized reports) – narzędzie odczytuje dane z wcześniej wygenerowanego, wersjonowanego zestawu wyników, który odzwierciedla stan bazy danych w określonym punkcie odcięcia. Paginacja lub dalsze obliczenia operują wówczas na tym zamrożonym zbiorze danych.

W SQL Server sprawdź, czy opcja READ_COMMITTED_SNAPSHOT jest aktywna. Nie zakładaj, że sama nazwa mówi wszystko.

Praktyczne zasady dla aplikacji napędzanych przez LLM

  • Grupuj to, co niezbędne (Batch what you need) – jeśli pytanie wymaga wielu wartości, oblicz je w ramach jednego wywołania narzędzia, zamiast wysyłać oddzielne zapytania, z których każde rozpoczyna nową transakcję.
  • Deterministyczna paginacja – przy prezentowaniu wyników na wielu stronach używaj stabilnego klucza sortowania, kursora lub zmaterializowanego zestawu wyników. Nigdy nie utrzymuj otwartej transakcji podczas przewijania strony przez użytkownika.
  • Zwracaj dowody (Return evidence) – obok danych dołącz metadane, które w sposób jawny określają model spójności: klasę spójności, czas rozpoczęcia migawki, punkt odcięcia raportowania, świeżość danych, liczbę wierszy, tożsamość bazy danych oraz identyfikator śledzenia (trace ID).
  • Przeprowadzaj testy obciążeniowe pod kątem współbieżności – symuluj równoległe zapisy podczas generowania promptów przez LLM i sprawdzaj, czy aplikacja poprawnie ponawia próby lub obsługuje błędy w sposób łagodny.

Wniosek jest jasny: czat AI nie powinien dyktować czasu trwania transakcji bazy danych. Poprzez ograniczenie zakresu spójności do każdego wywołania narzędzia, programiści dbają o zdrowie bazy danych, zachowują wydajność dla wszystkich użytkowników i zapewniają modelowi LLM wystarczającą ilość wiarygodnych danych do udzielania dokładnych odpowiedzi.