2009-12-22 22 views
5

En nuestra aplicación, hay una actualización de la base de datos que se confirma solo después de que se ejecuta una actualización (ambas usando la misma transacción, por supuesto). Sin embargo, hemos descubierto un flujo raro en el que el usuario sale de la aplicación antes de la segunda actualización, haciendo que la primera se descarte. Estoy buscando una forma de reconocer esta actualización no confirmada al salir.Indicando si una transacción tiene actualizaciones no confirmadas

Sé que problemas como este requieren un rediseño, pero eso no es posible. Debido a la rareza del flujo y la estructura de la aplicación, me pregunto si hay una forma de comprobar la transacción para ver si hay actualizaciones no confirmadas.

La pregunta es válida para Oracle y SQLServer. La aplicación está escrita en PowerBuilder, pero puede ampliarse de varias maneras (.NET, Win32, etc.) si eso es importante.

Respuesta

5

En Oracle puede llamar a DBMS_TRANSACTION.local_transaction_id. Esto devolverá un identificador único de la transacción actual o NULL si no hay ninguna transacción activa.

Comparte y disfruta.

4

Esto podría ser útil

@@TRANCOUNT (Transact-SQL)

Devuelve el número de transacciones activas para la conexión actual .

+0

Pensé que era SQL Server solamente? –

0

Para facilitar la resolución de problemas de su escenario, puede considerar el uso de transacciones locales con nombre explícito, junto con el uso de la opción "WITH MARK". Esto le permite registrar el nombre de una transacción explícita en el registro de transacciones, que por supuesto puede inspeccionar en una etapa posterior para identificar la secuencia de eventos que ha ocurrido.

consulte SQL Server Books Online: Marked Transactions

1

En Oracle hay una vista V$TRANSACTION que contiene una fila para cada transacción no confirmada. No hay ningún mecanismo para ver la naturaleza de esa transacción desde afuera (a menos que tenga instrumentación incorporada en su código, por ejemplo, usando DBMS_APPLICATION_INFO.SET_MODULE()). Sin embargo, la sesión actual podría ver si se ha UNCOMMITTED trabajo como este:

SQL> select t.status 
    2 from v$transaction t 
    3   join v$session s 
    4   on s.saddr = t.ses_addr 
    5 where s.sid = sys_context('userenv', 'sid') 
    6/

STATUS 
---------------- 
ACTIVE 

SQL> 

Si no hay transacciones no confirmadas entonces esta consulta devolverá NO_DATA_FOUND. Las vistas V $ no se otorgan a los usuarios de manera predeterminada, ya que en realidad son un DGA thang. Sin embargo, un usuario con el privilegio apropiado puede convertir esta consulta en una vista y otorgar acceso a las referencias regulares.

Como cuestión de interés, ¿qué te gustaría hacer? Presumiendo que la Unidad de trabajo está definida correctamente y tiene dos actualizaciones, seguramente sería incorrecto comprometer solo una. Si todo lo que desea saber es que esta terminación anormal ocurrió, entonces lo que necesita es algún tipo de rastreo o registro.

edición

Bob Jarvis proposes usando DBMS_TRANSACTION.LOCAL_TRANSACTION_ID(). Esa es una mejor sugerencia que una vista artesanal. La vista V $ TRANSACTION también se puede usar para supervisar transacciones no confirmadas de otras sesiones.

+0

Bueno, las dos actualizaciones no son realmente una unidad de trabajo. La actualización no confirmada es en realidad una llamada reencaminada a un servidor externo, que en lugar de transmitirse se almacena en la base de datos. Nuestra aplicación tiene un comportamiento constante en lo que respecta al compromiso, pero la actualización proviene de una parte diferente de la aplicación. Una transacción separada podría haber sido apropiada, pero eso también sería mucho trabajo. Entonces, debería estar bien confirmar la actualización no confirmada. – eran

0

En SQL Server, ejecute lo siguiente:

IF @@TRANCOUNT>0 BEGIN 
    ROLLBACK; 
END; 
2

Si estás en PB11.5 y utilizar un objeto de transacción a medida, es bastante fácil de hacer algo que no es dependiente de DBMS. En el evento SQLPreview del objeto transacción, simplemente active un booleano cuando INSERT, UPDATE o DELETE pasen, luego desactívelo cuando se produzca COMMIT o ROLLBACK.

En realidad, no es tan difícil intercambiar en un objeto de transacción personalizado si está utilizando SQLCA: Aplicación, Propiedades, Propiedades adicionales, Tipos de variables, SQLCA. Si usa muchas conexiones de bases de datos separadas con muchas declaraciones de "CREAR transacción" (la búsqueda PB estándar puede encontrar esto, o PBL Peeper puede ayudarlo a encontrar esto con una cantidad variable de espacios entre las palabras), entonces implementar esto será más difícil, pero no imposible.

Y, para completar, crear un objeto de transacción personalizado, Archivo/Nuevo/Objeto PB/Clase estándar/Transacción. Tiene un objeto de usuario común donde puede definir Variables de instancia (como el booleano que he sugerido) y eventos de secuencia de comandos (como el evento SQLPreview que he sugerido) y funciones (es posible que desee crear una interfaz para esta funcionalidad para ocultar los detalles en caso de que desee extenderlo en el futuro). Tenga en cuenta que SQLPreview no está disponible en el objeto Transaction antes de 11.5. (Para aquellos que piensan que suena familiar antes de 11,5, el DataWindow implementa un SQLPreview.)

Buena suerte,

Terry.

+0

Eso es bueno saber. Gracias, Terry! – eran

+0

No recibo COMMIT o ROLLBACK en la vista previa de SQL de las transacciones. PB 12.5, conexión ODBC. Esto realmente me duele porque hice una ingeniosa ventana tipo SQL Spy que muestra todo el SQL yendo a la base de datos, y convierte una gran barra indicadora en roja si hay una transacción no confirmada. –

Cuestiones relacionadas