Access 2000 Timeouts en un juego de registros encuadernado

Explosión del pasado ... Recibí la tarea de administrar un adp de Access 2000 antiguo que se usa para administrar datos que residen en el servidor SQL 2005. En uno de los formularios de datos, cada vez que intento realizar un cambio en un campo y guardar el cambio en la base de datos, se agota después de aproximadamente un minuto. El aumento del límite de tiempo de espera solo retrasa la visualización del mensaje de error de tiempo de espera. Pasé por todas las soluciones de problemas habituales para garantizar la compatibilidad (consulte, por ejemplo, esta pregunta SO).

Esta es la configuración: un formulario está vinculado a un conjunto de registros (que se lee de la base de datos como un SELECT * FROM table_name consulta. El conjunto de resultados varía en tamaño dependiendo de los filtros establecidos en el formulario, pero el resultado suele ser de alrededor de 200 registros (no muchos datos ...). Algunos de los campos del formulario desencadenan un guardado automático en un controlador de eventos asociado, que se parece a:

Private Sub EndDate_Exit(Cancel As Integer)
     some checking goes here...
     ...
     DoCmd.RunCommand acCmdSaveRecord
End Sub

Cuando siempre el DoCmd.RunCommand acCmdSaveRecord se ejecuta el código, el ADP se congela hasta que aparece un error de tiempo de espera. Profundizando un poco más, miré el Monitor de actividad en SQL Server. los acCmdSaveRecord desencadena un UPDATE declaración de regreso al servidor para guardar los datos modificados. MS Access construye automáticamente la declaración en sí en función de la clave principal de la tabla subyacente, que parece estar definida correctamente. Sin embargo, la actualización está bloqueada por un SELECT declaración, que corresponde a la SELECT * FROM table_name consulta mencionada anteriormente.

Esto conduce a un punto muerto: el cambio del usuario desencadena un UPDATE, que está bloqueado por una ejecución SELECT (que, como parece, se originó a partir del formulario que se está editando). ¿Cómo puedo evitar esto?

Cosas que hemos probado:

  1. Hemos eliminado el DoCmd.RunCommand acCmdSaveRecord declaración y lo reemplazó con el código Me.Dirty = False, que conduce exactamente al mismo comportamiento que el descrito anteriormente.
  2. Retiró el acCmdSaveRecord completar y utilizar el menú de acceso integrado para guardar el cambio. Esta es una funcionalidad equivalente a la # 1 y conduce exactamente al mismo comportamiento.
  3. Vuelva a colocar la acCmdSaveRecord llamar con un procedimiento almacenado que guarda el cambio en el campo específico. Funciona muy bien, excepto que guardar todo el registro de la GUI (botón de guardar que llama acCmdSaveRecord) conduce al mismo punto muerto.
  4. Se redujo el tamaño del conjunto de resultados asociado con el formulario a unos pocos registros. Curiosamente, todava exhibe el EXACT mismo comportamiento.

preguntado el 08 de noviembre de 11 a las 17:11

1 Respuestas

Parece que ha establecido el nivel de aislamiento de la transacción en SERIALIZABLE para su conexión en algún momento. Ver ESTABLECER EL NIVEL DE AISLAMIENTO DE LA TRANSACCIÓN (Transact-SQL) para más detalles. Aquí está el extracto aplicable (énfasis agregado):

SERIALIZABLE

Especifica lo siguiente:

  • Las declaraciones no pueden leer datos que hayan sido modificados pero que aún no hayan sido confirmados por otras transacciones.

  • Ninguna otra transacción puede modificar los datos leídos por la transacción actual hasta que se complete la transacción actual.

  • Otras transacciones no pueden insertar nuevas filas con valores clave que se encuentren en el rango de claves leídas por cualquier declaración en la transacción actual hasta que se complete la transacción actual.

Los bloqueos de rango se colocan en el rango de valores clave que coinciden con las condiciones de búsqueda de cada declaración ejecutada en una transacción. Esto bloquea otras transacciones para que no se actualicen o inserten filas que calificarían para cualquiera de las declaraciones ejecutadas por la transacción actual. Esto significa que si alguna de las declaraciones de una transacción se ejecuta por segunda vez, leerá el mismo conjunto de filas. Los bloqueos de rango se mantienen hasta que se completa la transacción. Este es el más restrictivo de los niveles de aislamiento porque bloquea rangos completos de claves y mantiene los bloqueos hasta que se completa la transacción. Debido a que la simultaneidad es menor, use esta opción solo cuando sea necesario. Esta opción tiene el mismo efecto que establecer HOLDLOCK en todas las tablas en todas las sentencias SELECT en una transacción.

Respondido el 20 de junio de 20 a las 12:06

Correcto. El nivel de aislamiento de TRansaction se estableció en READ COMMITTED, lo que evita las lecturas sucias, que fue lo que causó el problema. ¡Eres un salvavidas, gracias! - Ryan

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.