TN068: wykonywanie transakcji za pomocą sterownika Microsoft Access 7 ODBC Driver
Uwaga
Następująca uwaga techniczna nie została zaktualizowana, ponieważ została po raz pierwszy uwzględniona w dokumentacji online. W związku z tym niektóre procedury i tematy mogą być nieaktualne lub nieprawidłowe. Aby uzyskać najnowsze informacje, zaleca się wyszukanie interesującego tematu w indeksie dokumentacji online.
W tej notatce opisano sposób wykonywania transakcji w przypadku używania klas baz danych MFC ODBC i sterownika Microsoft Access 7.0 ODBC zawartego w pakiecie Sterowników klasycznych ODBC firmy Microsoft w wersji 3.0.
Omówienie
Jeśli aplikacja bazy danych wykonuje transakcje, należy zachować ostrożność, aby wywołać CDatabase::BeginTrans
metodę i CRecordset::Open
w odpowiedniej kolejności w aplikacji. Sterownik programu Microsoft Access 7.0 używa aparatu bazy danych Microsoft Jet, a narzędzie Jet wymaga, aby aplikacja nie rozpoczynała transakcji w żadnej bazie danych, która ma otwarty kursor. W przypadku klas baz danych MFC ODBC otwarty kursor odpowiada otwartemu CRecordset
obiektowi.
Jeśli otworzysz zestaw rekordów przed wywołaniem BeginTrans
metody , może nie zostać wyświetlony żaden komunikat o błędach. Jednak wszystkie aktualizacje zestawu rekordów, które aplikacja sprawia, że stają się trwałe po wywołaniu CRecordset::Update
metody , a aktualizacje nie zostaną wycofane przez wywołanie metody Rollback
. Aby uniknąć tego problemu, należy najpierw wywołać BeginTrans
metodę , a następnie otworzyć zestaw rekordów.
MFC sprawdza funkcjonalność sterownika pod kątem zachowania zatwierdzania kursora i wycofywania. Klasa CDatabase
udostępnia dwie funkcje GetCursorCommitBehavior
składowe i GetCursorRollbackBehavior
, aby określić wpływ dowolnej transakcji na otwarty CRecordset
obiekt. W przypadku sterownika ODBC programu Microsoft Access 7.0 te funkcje członkowskie zwracają SQL_CB_CLOSE
, ponieważ sterownik programu Access nie obsługuje zachowywania kursora. W związku z tym należy wywołać metodę CRecordset::Requery
CommitTrans
po operacji lub Rollback
.
Jeśli musisz wykonać wiele transakcji po drugiej, nie można wywołać Requery
po pierwszej transakcji, a następnie uruchomić następne. Musisz zamknąć zestaw rekordów przed następnym wywołaniem, BeginTrans
aby spełnić wymaganie Jet. Ta uwaga techniczna opisuje dwie metody obsługi tej sytuacji:
Zamykanie zestawu rekordów po każdej
CommitTrans
operacji lubRollback
.Za pomocą funkcji
SQLFreeStmt
interfejsu API ODBC .
Zamykanie zestawu rekordów po każdej operacji CommitTrans lub wycofywania
Przed rozpoczęciem transakcji upewnij się, że obiekt zestawu rekordów jest zamknięty. Po wywołaniu metody BeginTrans
wywołaj funkcję składową Open
zestawu rekordów. Zamknij zestaw rekordów natychmiast po wywołaniu metody CommitTrans
lub Rollback
. Należy pamiętać, że wielokrotne otwieranie i zamykanie zestawu rekordów może spowolnić wydajność aplikacji.
Korzystanie z narzędzia SQLFreeStmt
Możesz również użyć funkcji SQLFreeStmt
interfejsu API ODBC, aby jawnie zamknąć kursor po zakończeniu transakcji. Aby rozpocząć kolejną transakcję, wywołaj BeginTrans
metodę CRecordset::Requery
, a następnie . Podczas wywoływania SQLFreeStmt
metody należy określić HSTMT zestawu rekordów jako pierwszy parametr i SQL_CLOSE jako drugi parametr. Ta metoda jest szybsza niż zamykanie i otwieranie zestawu rekordów na początku każdej transakcji. Poniższy kod pokazuje, jak zaimplementować tę technikę:
CMyDatabase db;
db.Open("MYDATASOURCE");
CMyRecordset rs(&db);
// start transaction 1 and
// open the recordset
db.BeginTrans();
rs.Open();
// manipulate data
// end transaction 1
db.CommitTrans(); // or Rollback()
// close the cursor
::SQLFreeStmt(rs.m_hstmt, SQL_CLOSE);
// start transaction 2
db.BeginTrans();
// now get the result set
rs.Requery();
// manipulate data
// end transaction 2
db.CommitTrans();
rs.Close();
db.Close();
Innym sposobem zaimplementowania tej techniki jest napisanie nowej funkcji , RequeryWithBeginTrans
którą można wywołać w celu uruchomienia następnej transakcji po zatwierdzeniu lub wycofaniu pierwszego. Aby napisać taką funkcję, wykonaj następujące czynności:
Skopiuj kod do
CRecordset::Requery( )
nowej funkcji.Dodaj następujący wiersz bezpośrednio po wywołaniu metody
SQLFreeStmt
:m_pDatabase->BeginTrans( );
Teraz możesz wywołać tę funkcję między każdą parą transakcji:
// start transaction 1 and
// open the recordset
db.BeginTrans();
rs.Open();
// manipulate data
// end transaction 1
db.CommitTrans(); // or Rollback()
// close the cursor, start new transaction,
// and get the result set
rs.RequeryWithBeginTrans();
// manipulate data
// end transaction 2
db.CommitTrans(); // or Rollback()
Uwaga
Nie należy używać tej techniki, jeśli musisz zmienić zmienne składowe zestawu rekordów m_strFilter lub m_strSort między transakcjami. W takim przypadku należy zamknąć zestaw rekordów po każdej CommitTrans
operacji lub Rollback
.
Zobacz też
Uwagi techniczne według numerów
Uwagi techniczne według kategorii