TN068: Microsoft Access 7 ODBC 드라이버를 사용하여 트랜잭션 수행

참고 항목

다음 기술 노트는 온라인 설명서에 먼저 포함되어 있었으므로 업데이트되지 않았습니다. 따라서 일부 절차 및 항목은 만료되거나 올바르지 않을 수 있습니다. 최신 정보를 보려면 온라인 설명서 색인에서 관심 있는 항목을 검색하는 것이 좋습니다.

이 참고에서는 MFC ODBC 데이터베이스 클래스 및 Microsoft ODBC 데스크톱 드라이버 팩 버전 3.0에 포함된 Microsoft Access 7.0 ODBC 드라이버를 사용할 때 트랜잭션을 수행하는 방법을 설명합니다.

개요

데이터베이스 애플리케이션이 트랜잭션을 수행하는 경우 애플리케이션에서 올바른 순서로 호출 CDatabase::BeginTransCRecordset::Open 해야 합니다. Microsoft Access 7.0 드라이버는 Microsoft Jet 데이터베이스 엔진을 사용하며 Jet는 열려 있는 커서가 있는 데이터베이스에서 애플리케이션이 트랜잭션을 시작하지 않도록 요구합니다. MFC ODBC 데이터베이스 클래스의 경우 열려 있는 커서가 열린 CRecordset 개체와 동일합니다.

호출 BeginTrans하기 전에 레코드 집합을 열면 오류 메시지가 표시되지 않을 수 있습니다. 그러나 호출한 후 애플리케이션이 영구적으로 업데이트하는 레코드 집합 업데이트는 호출CRecordset::UpdateRollback을 통해 롤백되지 않습니다. 이 문제를 방지하려면 먼저 호출 BeginTrans 한 다음 레코드 집합을 열어야 합니다.

MFC는 커서 커밋 및 롤백 동작에 대한 드라이버 기능을 검사. 클래스 CDatabase 는 두 개의 멤버 함수를 GetCursorCommitBehavior 제공하며 GetCursorRollbackBehavior, 열려 CRecordset 있는 개체에 대한 트랜잭션의 영향을 확인합니다. Microsoft Access 7.0 ODBC 드라이버의 경우 Access 드라이버가 커서 유지를 지원하지 않으므로 이러한 멤버 함수가 반환 SQL_CB_CLOSE 됩니다. 따라서 다음 CommitTrans 또는 Rollback 작업을 호출 CRecordset::Requery 해야 합니다.

여러 트랜잭션을 하나씩 수행해야 하는 경우 첫 번째 트랜잭션 이후에 호출 Requery 한 다음 다음 트랜잭션을 시작할 수 없습니다. Jet의 요구 사항을 충족하려면 다음 호출 BeginTrans 전에 레코드 집합을 닫아야 합니다. 이 기술 참고에서는 이 상황을 처리하는 두 가지 방법을 설명합니다.

  • CommitTrans 또는 Rollback 작업 후에 레코드 집합을 닫습니다.

  • ODBC API 함수 SQLFreeStmt사용.

각 CommitTrans 또는 롤백 작업 후 레코드 집합 닫기

트랜잭션을 시작하기 전에 레코드 집합 개체가 닫혀 있는지 확인합니다. 호출 BeginTrans한 후 레코드 집합의 Open 멤버 함수를 호출합니다. 호출 CommitTrans 후 바로 레코드 집합을 닫거나 Rollback. 레코드 집합을 반복적으로 열고 닫으면 애플리케이션의 성능이 저하될 수 있습니다.

SQLFreeStmt 사용

ODBC API 함수 SQLFreeStmt 를 사용하여 트랜잭션을 종료한 후 커서를 명시적으로 닫을 수도 있습니다. 다른 트랜잭션을 시작하려면 다음을 호출 BeginTrans 합니다 CRecordset::Requery. 호출 SQLFreeStmt할 때 레코드 집합의 HSTMT를 첫 번째 매개 변수로 지정하고 두 번째 매개 변수로 SQL_CLOSE 합니다. 이 메서드는 모든 트랜잭션이 시작될 때 레코드 집합을 닫고 여는 것보다 빠릅니다. 다음 코드는 이 기술을 구현하는 방법을 보여 줍니다.

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();

이 기술을 구현하는 또 다른 방법은 새 함수를 작성하는 것입니다. 이 함수는 첫 번째 함수 RequeryWithBeginTrans를 커밋하거나 롤백한 후 다음 트랜잭션을 시작하도록 호출할 수 있습니다. 이러한 함수를 작성하려면 다음 단계를 수행합니다.

  1. 새 함수에 대한 CRecordset::Requery( ) 코드를 복사합니다.

  2. 호출 직후에 다음 줄을 추가합니다 SQLFreeStmt.

    m_pDatabase->BeginTrans( );

이제 각 트랜잭션 쌍 간에 이 함수를 호출할 수 있습니다.

// 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()

참고 항목

트랜잭션 간에 m_strFilter 또는 m_strSort 레코드 집합 멤버 변수를 변경해야 하는 경우 이 기술을 사용하지 마세요. 이 경우 각 CommitTrans 또는 Rollback 작업 후에 레코드 집합을 닫아야 합니다.

참고 항목

번호별 기술 참고 사항
범주별 기술 참고 사항