TN068: Realizar transacciones con el controlador ODBC de Microsoft Access 7

Esta nota describe cómo realizar las transacciones cuando se utilizan las clases de base de datos ODBC de MFC y el controlador ODBC de Microsoft Access 7.0 incluido en la versión de escritorio de Microsoft ODBC Driver Pack 3.0.

Visión general

Si su aplicación de base de datos realiza transacciones, debe tener cuidado al llamar a CDatabase::BeginTrans y ser en la secuencia correcta en su aplicación. El controlador de Microsoft Access 7.0 utiliza el motor de base de datos Microsoft Jet y Jet requiere que su aplicación no comenzar una transacción en cualquier base de datos que tiene un cursor abierto. Para las clases de base de datos ODBC de MFC, un cursor abierto equivale a un objeto CRecordset abierto.

Si abrir un objeto recordset antes de llamar a BeginTrans, no puede ver los mensajes de error. Sin embargo, las actualizaciones de registros que su aplicación hace que se convierta en permanente después de llamar a CRecordset:: Updatey las actualizaciones no se revertirán llamando Rollback. Para evitar este problema, debe llamar a BeginTrans primero y luego abrir el recordset.

MFC comprueba la funcionalidad del controlador para el comportamiento de commit y rollback de cursor. Clase CDatabase proporciona dos funciones miembro, GetCursorCommitBehavior y GetCursorRollbackBehavior, para determinar el efecto de cualquier transacción en su objeto CRecordset abierto. Para el controlador ODBC de Microsoft Access 7.0, estas funciones miembro volver SQL_CB_CLOSE porque el controlador de acceso no compatible con preservación de cursor. Por lo tanto, se debe llamar a CRecordset::Requery después de una operación CommitTrans o Rollback.

Cuando necesita realizar múltiples transacciones uno tras otro, no se puede llamar a Requery después de la primera transacción e inicie cada uno. Debe cerrar el recordset antes de la siguiente llamada a BeginTrans a fin de satisfacer el requisito del Jet. Esta nota técnica describe dos métodos de manejar esta situación:

Cierre de los registros después de cada operación de deshacer o CommitTrans

Antes de iniciar una transacción, asegúrese de que el objeto recordset está cerrado. Después de llamar a BeginTrans, llamar la función miembro Open del conjunto de registros. Cerrar el recordset inmediatamente después de llamar a CommitTrans o Rollback. Tenga en cuenta que varias veces abriendo y cerrando el recordset pueden ralentizar el rendimiento de una aplicación.

Utilizando SQLFreeStmt

También puede utilizar la función de la API de ODBC SQLFreeStmt para cerrar explícitamente el cursor después de terminar una transacción. Para iniciar otra transacción, llame a BeginTrans seguido por CRecordset::Requery. Al llamar a SQLFreeStmt, debe especificar HSTMT del conjunto de registros como primer parámetro y SQL_CLOSE como segundo parámetro. Este método es más rápido que cerrar y abrir el recordset al comienzo de cada transacción. El código siguiente muestra cómo implementar esta técnica

 CMyDatabase db;
DB.Open ("MIORIGENDED&ATOS");
CMyRecordset rs (amp; db);

/ / iniciar la transacción 1 y / / abrir el recordset
DB.() BeginTrans;
RS.(Abierto);

/ / manipular datos

/ / final de transacción 1
DB.CommitTrans (de);  y / o Rollback)

/ / cerrar el cursor
:: SQLFreeStmt (rs.m_hstmt, SQL_CLOSE);

/ / iniciar la transacción 2
DB.() BeginTrans;

/ / obtener ahora el conjunto de resultados
RS.Requery ();

/ / manipular datos

/ / final de transacción 2
DB.CommitTrans (de);

RS.(Cerrar);
DB.(Cerrar)

Otra forma de aplicar esta técnica consiste en escribir una nueva función, RequeryWithBeginTrans, que se puede llamar para iniciar la siguiente transacción después de confirmar o deshacer la primera de ellas. Para escribir esta función, siga estos pasos:

  1. Copie el código de CRecordset::Requery () en la nueva función.

  2. A&gregue la siguiente línea inmediatamente después de la llamada a SQLFreeStmt:
    m_pDatabase-gt;BeginTrans( );

Ahora puede llamar a esta función entre cada par de transacciones:

/ / i&niciar la transacción 1 y / / abrir el recordset
DB.() BeginTrans;
RS.(Abierto);

/ / manipular datos

/ / final de transacción 1
DB.CommitTrans (); nbsp; y / o Rollback)

/ / cerrar el cursor, inicia nueva transacción,
/ / y obtener el conjunto de resultados
RS.(De RequeryWithBeginTrans);

/ / manipular datos

/ / final de transacción 2
DB.CommitTrans (de);  y / o Rollback)

&Notanbsp;  No utilice esta técnica si necesita cambiar el recordset miembro variables m_strFilter o m_strSort entre transacciones. En ese caso, debe cerrar los registros después de cada operación CommitTrans o Rollback.

&Notas técnicas por número |nbsp; Notas técnicas por categoría

Index