Error de Transacciones con COM+

22/02/2006 - 20:21 por AOG | Informe spam
Hola tengo el siguiente problema:
Tengo un solucion en VB 2005 en la que utilizo EnterpriseServices entre
otras cosas para la gestión de transacciones en la capa de negocio hacia el
acceso a datos, este proyecto puede gestionar indistintamente una base de
datos MS Sql Server o MySQL (me he implementado un interfaz en el acceso a
datos) , hago esta puntualización porque cuando le digo al proyecto que
utilize la base de datos MySql no hay problemas. Cuando el proyecto ataca al
la base de datos MS SQLServer me da el siguiente error:

{"La transacción ya se ha llevado a cabo o se ha cancelado implícita o
explícitamente (Exception from HRESULT: 0x8004D00E)"}

El componente funciona de la siguiente forma:

Componente A --> Componente B --> Acceso a Base de datos.

Según he leido lo que puede pasar es que el componente B
realice un Abort y el componente A un Commit. El problema
es que el componente B no realiza Abort ni Commit en
ningún lado (tiene "Supported", tampoco tiene AutoComplete
()), es decir el que se encargada de hacer eso es el
Componente A (que tiene "Requires", también he probado Requires New).

Tambien probé deshabilitando las transacciones, es decir, ejecutar las COM
sin transaccionalidad y me funcionó bien. Esto lo hice para despejar
cualquier duda sobre problemas de conexión entre las maquinas y de red,
además, los dos servidores de SQL (Mysql y MS Sql) está en la misma máquina,
si tengo que decir que mi máquina de desarrollo no es la misma, es decir,
tengo el proyecto en un PC distindo en donde se aloja los Servidores SQL. Es
más cuando se inicia la aplicación pide usuario y conecta con la BBDD sin
problemas, claro, porque ahí no utilizo nada de transacciones ni componentes
COM+, pero cuando utilizo por ejemplo cualquier mantenimiento me salta el
error.
Bueno, no he dicho cuando se proboca el error, y es cuando ejecuto la
instrucción
MyConexion.Open(), a intentar abrir la conexión, hago llamada al componete
de negocio de MoverRegistroSiguiente, este llama a la capa de acceso a datos
MoverRegistroSiguiente en la cual llama al interfaz para abrir conexión y me
da el error.
En la cabecera de la clase de la capa de negocio tiene puesto:
<EnterpriseServices.ObjectPooling(minPoolSize:=INT_Pooling_MIM_PoolSize,
maxPoolSize:=INT_Pooling_MAX_PoolSize,
CreationTimeout:=INT_Pooling_CreationTimeout)> _
<EnterpriseServices.JustInTimeActivation()> _
<System.EnterpriseServices.TransactionAttribute( _
System.EnterpriseServices.TransactionOption.Required)> _
Public Class MantemimientoCN
'// He probado con <AutoComplete()> y sin <AutoComplete()> y da error
'<AutoComplete()> _
Public Function MoverRegistroSiguiente(Byval dt as DataSet) as
DataSet
Return oMateAD.MoverRegistroSiguiente(dt)
End Function
End Class
Bueno espero que con esta información, me puedas ayudar a solucionar este
problema.

Un saludo.
 

Leer las respuestas

#1 Jesús López
22/02/2006 - 20:35 | Informe spam
Algunas recomendaciones:

- Desactiva todo Object Pooling. El Object Pooling es muy problemático con
objetos transacionales.
- Marca todos los métodos con AutoComplete()
- El objeto raíz (Componente A) debería tener TransactionRequied o
TransactionNew
- Los demás objetos deberían tener TransactionRequired.

El único atributo que necesitan las clases es el de
Transaction(TransactionOption.Required). El de object pooling es un incordio
y los demás son implicitos a los objetos transacionales: JustInTime y
Synchronization.

Ojo: con MySql no tienes ningún problema, porque MySql no soporta
transacciones manejadas por el MSDTC. Las conexiones MySql "NO" se enlistan
automáticamente en la transacción activa. Es decir, usar MySql en un objeto
transacional COM+ es como usarlo en un objeto no COM+. Dicho de otra manera,
a MySql le importa muy poco si el objeto es transacional o no.

Saludos:

Jesús López
MVP



"AOG" escribió en el mensaje
news:
Hola tengo el siguiente problema:
Tengo un solucion en VB 2005 en la que utilizo EnterpriseServices entre
otras cosas para la gestión de transacciones en la capa de negocio hacia
el
acceso a datos, este proyecto puede gestionar indistintamente una base de
datos MS Sql Server o MySQL (me he implementado un interfaz en el acceso a
datos) , hago esta puntualización porque cuando le digo al proyecto que
utilize la base de datos MySql no hay problemas. Cuando el proyecto ataca
al
la base de datos MS SQLServer me da el siguiente error:

{"La transacción ya se ha llevado a cabo o se ha cancelado implícita o
explícitamente (Exception from HRESULT: 0x8004D00E)"}

El componente funciona de la siguiente forma:

Componente A --> Componente B --> Acceso a Base de datos.

Según he leido lo que puede pasar es que el componente B
realice un Abort y el componente A un Commit. El problema
es que el componente B no realiza Abort ni Commit en
ningún lado (tiene "Supported", tampoco tiene AutoComplete
()), es decir el que se encargada de hacer eso es el
Componente A (que tiene "Requires", también he probado Requires New).

Tambien probé deshabilitando las transacciones, es decir, ejecutar las COM
sin transaccionalidad y me funcionó bien. Esto lo hice para despejar
cualquier duda sobre problemas de conexión entre las maquinas y de red,
además, los dos servidores de SQL (Mysql y MS Sql) está en la misma
máquina,
si tengo que decir que mi máquina de desarrollo no es la misma, es decir,
tengo el proyecto en un PC distindo en donde se aloja los Servidores SQL.
Es
más cuando se inicia la aplicación pide usuario y conecta con la BBDD sin
problemas, claro, porque ahí no utilizo nada de transacciones ni
componentes
COM+, pero cuando utilizo por ejemplo cualquier mantenimiento me salta el
error.
Bueno, no he dicho cuando se proboca el error, y es cuando ejecuto la
instrucción
MyConexion.Open(), a intentar abrir la conexión, hago llamada al componete
de negocio de MoverRegistroSiguiente, este llama a la capa de acceso a
datos
MoverRegistroSiguiente en la cual llama al interfaz para abrir conexión y
me
da el error.
En la cabecera de la clase de la capa de negocio tiene puesto:
<EnterpriseServices.ObjectPooling(minPoolSize:=INT_Pooling_MIM_PoolSize,
maxPoolSize:=INT_Pooling_MAX_PoolSize,
CreationTimeout:=INT_Pooling_CreationTimeout)> _
<EnterpriseServices.JustInTimeActivation()> _
<System.EnterpriseServices.TransactionAttribute( _
System.EnterpriseServices.TransactionOption.Required)> _
Public Class MantemimientoCN
'// He probado con <AutoComplete()> y sin <AutoComplete()> y da
error
'<AutoComplete()> _
Public Function MoverRegistroSiguiente(Byval dt as DataSet) as
DataSet
Return oMateAD.MoverRegistroSiguiente(dt)
End Function
End Class
Bueno espero que con esta información, me puedas ayudar a solucionar este
problema.

Un saludo.

Preguntas similares