Foros del Web » Programando para Internet » ASP Clásico »

Problema Transacciones ASP+ACCESS

Estas en el tema de Problema Transacciones ASP+ACCESS en el foro de ASP Clásico en Foros del Web. Hola a todos: Tengo unos formularios que realizan inserciones en una base de datos ACCESS utilizando transacciones . Se trata de un proceso de inserción ...
  #1 (permalink)  
Antiguo 03/04/2003, 03:53
 
Fecha de Ingreso: mayo-2002
Mensajes: 66
Antigüedad: 22 años, 11 meses
Puntos: 0
Problema Transacciones ASP+ACCESS

Hola a todos:

Tengo unos formularios que realizan inserciones en una base de datos ACCESS utilizando transacciones.

Se trata de un proceso de inserción en varios pasos ( 1 de 3, 2 de 3, 3 de 3) de manera que cuando un usuario está en el paso 1 de 3 y envía el formulario, un ASP recibe los datos, los valida, empieza una transacción (BeginTrans) y guarda los datos en la BDD. A continuación se le muestra el formulario del paso 2 de 3. Y así sucesivamente hasta el final.

La aceptación o cancelación de la transacción se realiza al final del paso 3 de 3, en el caso de que todo haya ido bien y todos los datos recibidos sean correctos.

Hasta aquí está todo claro.

El problema aparece cuando hay actualizaciones concurrentes .

Si mientras un usuario A está en el paso 2 de 3 (en mitad de una transacción), llega otro usuario B diferente e intenta hacer el paso 1 de 3, se produce este error:

Código:
Microsoft OLE DB Provider for ODBC Drivers error '80040e21' 

[Microsoft][Controlador ODBC Microsoft Access 97] No se pudo
 actualizar; actualmente está bloqueado por el usuario <user> en 
la máquina <nombre_maquina>. 

/tarificadores/asistencia sanitaria/backend/modalidadesBD.asp, line 100
La porción de código que provoca el error es esta:
Código:
[...]
87 sql = "SELECT * FROM modalidades"
88 objRS.Open sql, oConn, 3, 3
89 objRS.AddNew
90 objRS("nombre") = request.form("nombre")
91 objRS("id_companyia") = request.form("idCompanyia")
92 objRS("edad_minima") = request.form("edadMinima")
[...]
99 objRS("id_cuadro") = request.form("idCuadro") 
100 objRS.update 
[...]
Y ante esto mi pregunta es:


¿Hay alguna forma de utilizar transacciones de manera que se puedan hacer actualizaciones de varios usuarios diferentes?


He buscado información sobre métodos del objeto Connection, pero no he encontrado nada.

¿Alguna idea?
Muchas gracias de antemano.
__________________
Un saludo,

Alberto
  #2 (permalink)  
Antiguo 03/04/2003, 14:56
Avatar de cacike500  
Fecha de Ingreso: noviembre-2002
Mensajes: 56
Antigüedad: 22 años, 5 meses
Puntos: 0
Control de simultaneidad

El control de simultaneidad determina que ocurrirá cuando dos usuarios intenten
actualizar la misma fila. Para especificar cómo ADO deba manejar la simultaneidad,
use la propiedad LockType del objeto Recordset, que puede tener una de los siguientes valores:

adLockReadOnly: Se utiliza cuando solo no se necesita
actualizar sus filas (modo de solo lectura).
adLockPessimistic: La fila se bloquea cuando una aplicación
comienza a editarla. Los otros
usuarios podrán verla pero no modificarla.
El bloqueo se elimina cuando la
aplicación que lo generó actualice la fila.
Se utiliza para operaciones poco
frecuentes y delicadas y debe ser
liberado en el menor tiempo posible
para que los demás usuarios puedan
acceder a la fila lo antes posible.
adLockOptimistic: La base de datos coloca un bloqueo en
las filas mientras las actualiza que dura
un instante. Este tipo de bloqueo presupone
que la posibilidad de que dos
usuarios editen la misma fila a la vez es
muy remota.
adLockBatchOptimistic: Se usa cuando re crea el cursor, desconectamos,
actualizamos y después volvemos
a conectar para que la actualización
quede reflejada en la base de datos.
Actualización por lotes.
__________________
como dice un sabio amigo mio:
web puede...
master algo menos...
[AIG...2001]
  #3 (permalink)  
Antiguo 04/04/2003, 01:32
 
Fecha de Ingreso: mayo-2002
Mensajes: 66
Antigüedad: 22 años, 11 meses
Puntos: 0
Hola Cacique:

Gracias por tu respuesta. En su momento pensé que el problema se debía a lo que comentas, e hice los cambios correspondientes. Si te fijas, la linea 88 es:

Código:
objRS.Open sql, oConn, 3, 3
donde el primer 3 indica el tipo de cursor y el segundo 3 indica el tipo de cerrojo.

Según esa línea el RecordSet obtenido utilizaría un cursor de tipo "adOpenStatic" y un cerrojo de tipo "adLockOptimistic".

Es decir que la linea 88 es totalmente equivalente a:

Código:
objRS.Open sql, oConn, adOpenStatic, adLockOptimistic
Y a pesar de eso, sigo sin resolver el problema.
¿Alguna idea?

Ayuda maestros!!!!

Gracias de antemano
__________________
Un saludo,

Alberto
  #4 (permalink)  
Antiguo 05/04/2003, 14:14
Avatar de cacike500  
Fecha de Ingreso: noviembre-2002
Mensajes: 56
Antigüedad: 22 años, 5 meses
Puntos: 0
Tienes razón no me había fijado. Luego de leer detenidamente el código creo que tu problema está en el tipo de cursor:

Tú utilizas el siguiente cursor:
Cursores estáticos (adOpenStatic): El cursor estático es una
instantánea de l base de datos en el momento de la creación del
cursor. Permite su navegación en ambas direcciones. Sin embargo,
no permite ver las modificaciones que otros usuarios hagan e
las filas del cursor. Para actualizar un Recordset estático utilice los
ya visitadas.

Mi sugerencia es uno de los siguientes:
Cursor controlado por conjunto de claves (adOpenKeyset):
Este tipo de cursor no extrae las filas de la base de datos, sino
que las marca para extraerlas una a una del servidor. Esto permite que si otro usuario modifica una de las filas del cursor al tener que
obtener la fila directamente del servidor y la recibiremos con los
nuevo valores. De la misma forma, si una fila es eliminada por otro
usuario, cuando el cursor va a obtener la fila de la base de datos
al no encontrarla se la salta. Lo que no permite hacer este cursor
es ver las nuevas inserciones, porque una vez hecha la consulta
aunque se añada una fila que cumpla con los criterios de la misma,
el cursor ya tiene su conjunto de claves asignado y no las actualiza.
Cursores dinámicos (adOpenDynamic): Son muy similares a
los anteriores aunque solucionando su pequeño defecto. Si otro
usuario añadiese una fila a la base de datos que cumpliese con
las condiciones impuestas por la consulta de creación del cursor,
ésta se añade automáticamente al conjunto de claves, por lo tanto
será visible para la aplicación. El defecto de este tipo de cursor es
que no se puede saber cuantos registros hay en el Recordset ya
que el conjunto de claves no es fijo.
__________________
como dice un sabio amigo mio:
web puede...
master algo menos...
[AIG...2001]
  #5 (permalink)  
Antiguo 07/04/2003, 03:18
 
Fecha de Ingreso: mayo-2002
Mensajes: 66
Antigüedad: 22 años, 11 meses
Puntos: 0
Pregunta

Hola cacike500:

Muchas gracias, otra vez, por tus comentarios.
He hecho pruebas tanto con cursores de tipo "adOpenKeyset" como "adOpenDynamic" y el resultado es siempre el mismo:

Código:
Microsoft OLE DB Provider for ODBC Drivers error '80040e21' 

[Microsoft][Controlador ODBC Microsoft Access 97] No se pudo
 actualizar; actualmente está bloqueado por el usuario <user> en 
la máquina <nombre_maquina>. 

/tarificadores/asistencia sanitaria/backend/modalidadesBD.asp, line 100
Por eso pienso que _tal vez_ el problema esté en alguna propiedad de la conexión (¿tal vez alguna que indique el modo de actualización en las transacciones? No lo sé... )

Mirando las propiedades del objeto Connection veo que hay 2 propiedades ``sospechosas" que podrían tener relación con esto:

1) IsolationLevel

y

2) Mode

Están poco documentadas (en el libro que uso) pero es un comienzo. ¿Conoces estas propiedades? ¿Sabes si guardan relación con los bloqueos de la BDD en las transacciones?

Si hago un response.write de la primera propiedad obtengo el valor ``4096". Viendo el fichero ADOVBS.inc ese valor se corresponde con ``&H00001000" (en hexadecimal) o lo que es lo mismo ``adXactReadCommitted", lo cual no tengo ni idea de lo que significa.

En cuanto a la segunda propiedad, el valor obtenido es 0 que se corresponde con ``adModeUnknown". He probado a asignar el modo ``adModeReadWrite" (antes de abrir la conexión) y no da errores, pero tampoco resuelve el problema: sigue sin permitir que otros usuarios inserten/actualicen registros en la BDD.

CONCLUSIÓN: Esto empieza a ser un reto sólo para maestros... así que a ver si alguien se anima

: Ayuda!!!!!!!! :

Alguna idea???

Muchas gracias de antemano.
__________________
Un saludo,

Alberto
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:38.