[Indice]


el objeto ObjectContext

Este objeto se utiliza para controlar las transacciones de datos que se realizan en ASP a través del MTS... Aunque puede que no sepas lo que es el MTS ni una transacción.

Como transacción entenderemos cualquier movimiento de datos que se produzca entre el servidor web y el cliente que solicita los datos, entendiendo este movimiento como un conjunto. Si éste movimiento se realiza por completo, sin producirse ningun error, entonces se dice que la transacción ha concluido en commit, y si no termina bien, por producirse algún problema en la DB, en el código SQL de la consulta, en el código ASP o por no cumplirse alguna condición de las programadas en la aplicación, se dice que la transacción ha concluido en abort.

Por ejemplo, imaginemos una típica aplicación de comercio electrónico. En primer lugar el usuario se da de alta como cliente, y a continuación hace un pedido cualquiera. Por cualquier razón se produce un fallo cuando la aplicación va a guardar el pedido en la base de datos. En ese momento, MTS entraría en acción y anularía toda la transacción, incluida el alta del cliente que sí terminó bien.

Haría falta todo un libro para explicar como funciona el MTS (Microsoft Transaction Server), así que nos conformaremos con saber que es una especie de "intermediario" entre el IIS y el sistema. Se instala automáticamente durante el proceso de instalación del Option Pak (no confundir con los Service Pak, que son actualizaciones del sistema operativo) para Windows NT Server, que es el paquete que instala el IIS con las extensiones ASP en el servidor. El MTS controla los recursos físicos y lógicos necesarios para que las transacciones con el cliente funcionen lo mejor posible, sin interferirse unas con otras, y liberando los recursos cuando éstas terminan. La razón de su existencia es, además de la optimización de recursos, la de poder controlar si una transacción ha concluido correctamente o no en tiempo real, cosa que, sin el MTS, sólo es posible saber cuando se produce un error por tiempo excedido, es decir, mucho tiempo después de haberse producido el error.

Para poder utilizar este objeto, hay que invocar primero una directiva de ASP llamada @Transaction, y que debe escribirse antes que cualquier otra línea de código de las necesarias para producir la transacción.

El objeto ObjectContext tiene 2 métodos y 2 eventos:


METODOS

ObjectContext.SetComplete - ObjectContext.SetAbort

Estos métodos declaran explícitamente que una transacción ha sido completada o no, y dejan preparados sus recursos para que puedan ser actualizados. En ese momento, y si están definidos en el programa, los eventos OnTransactionCommit o OnTransactionAbort, pertenecientes al mismo objeto ObjectContext, son procesados.


EVENTOS

ObjectContext.OnTransactionAbort()

Este evento se produce cuando una transacción aborta debido a un error de programa (como una instrucción incongruente) o de proceso (por ejemplo, la DB no encuentra los datos pedidos, por lo que no puede enviarlos al cliente, es decir, la transacción no puede realizarse). ObjectContext.OnTransactionAbort no es más que una simple subrutina, con un nombre reservado, del estilo de las existentes en el fichero global.asa, pero que puede ser invocada solamente desde el código de la página que se está procesando. Es decir, cada página ASP escrita deberá tener su propia subrutina para llamar al evento; no es una variable de sesión ni de aplicación al alcance de otras páginas de la aplicación.

El siguiente ejemplo contiene una incongruencia de programa. Tiene limitado el tiempo de ejecución a 5 segundos. Como su proceso normal necesita más tiempo, se produce un evento OnTransactionAbort:

<%
@Transaction=Required Language="VBScript"
Response.Buffer = TRUE
Server.ScriptTimeout = 5
%>
<HTML>
<HEAD><TITLE>PRUEBA</TITLE></HEAD>
<BODY>
<%
Do
    x=x+1
    Response.Write x & "<BR>"
Loop While x < 10000
%>
</BODY>
</HTML>

Sub OnTransactionAborted()
Response.Write "La transacción ha abortado por exceso de tiempo en su ejecución."
End Sub

Y este sería el resultado:

La transacción ha abortado por exceso de tiempo en su ejecución.


ObjectContext.OnTransactionCommit()

Este evento se produce cuando una transacción termina correctamente. ObjectContext.OnTransactionCommit no es más que una simple subrutina, con un nombre reservado, del estilo de las existentes en el fichero global.asa, pero que puede ser invocada solamente desde el código de la página que se está procesando. Es decir, cada página ASP escrita deberá tener su propia subrutina para llamar al evento; no es una variable de sesión ni de aplicación al alcance de otras páginas de la aplicación.

El siguiente ejemplo no contiene ningún error de programa. Como su proceso terminará normalmente, se produce un evento OnTransactionCommit :

<% @Transaction=Required Language="VBScript" %>
<HTML>
<HEAD><TITLE>PRUEBA</TITLE></HEAD>
<BODY>
<%
Do
    x=x+1
    Response.Write x & "<BR>"
Loop While x < 5
%>
</BODY>
</HTML>

Sub OnTransactionCommit()
Response.Write "La transacción ha terminado correctamente"
End Sub

Sub OnTransactionAborted()
Response.Write "La transacción ha abortado por exceso de tiempo en su ejecución."
End Sub

Y este sería el resultado:

1
2
3
4
5
La transacción ha terminado correctamente.


Un ejemplo completo

He aquí un ejemplo ya conocido, implementando estos métodos y eventos:

<% @Transaction=Required Language="VBScript" %>
<HTML>
<HEAD><TITLE>PRUEBA</TITLE></HEAD>
<BODY>
<%
Set DB = Server.CreateObject("ADODB.Connection")
Set RS = Server.CreateObject("ADODB.RecordSet")

SQL ="SELECT convert(char(8), nom_dni) + nom_nif AS 'NIF', " & _
     "nom_apellidos AS 'Apellidos', "  & _
     "nom_nombre AS 'Nombre', " & _
     "nom_postal AS 'Postal' " & _
     "nom_postal + ' ' + nom_localidad AS 'Localidad', " & _
     "nom_provincia AS 'Provincia' " & _
     "FROM nombres WHERE nom_dni = 12345678 "

DB.Open "DB_nombre", "DB_user", "DB_password"
RS.Open SQL, DB

If RS.EOF AND RS.BOF Then
   ObjectContext.SetAbort
 Else
   Response.Write("<TABLE BORDER=1>")

   For i = 0 to RS.Fields.Count - 1
       Response.Write("<TR><TH>") 
       Response.Write(RS(i).Name)
       Response.Write("</TH><TD>")
       Response.Write(RS(i))
       Response.Write("</TD></TR>")
   Next
   Response.Write("</TABLE> <P>")
   ObjectContext.SetComplete
End if
RS.Close
Set RS = Nothing
DB.Close
Set DB = Nothing
%>
</BODY>
</HTML>

Sub OnTransactionAborted()
  Response.Write "Transacción abortada. No se encontraron registros"
End Sub

Sub OnTransactionCommit()
  Response.Write "Transacción realizada."
End Sub

Si todo termina bien, éste sería el resultado:

NIF12345678Z
ApellidosGarcia
NombreJuan
Postal12345
Localidad12345 Villa Desconocida
ProvinciaGuadalajara

Transacción realizada.

Y si el registro buscado no se encuentra, al no concluir la transacción, solamente obtendremos esto:

Transacción abortada. No se encontraron registros


[Indice]