Pregunta: Existe alguna opcion en Evolution para evitar que se inicie una TRANSACCION (Begin Transaction y Commit Transaction) al momento de enviar a AUTORIZACION una ENTIDAD?

Importancia: Alta y Urgente

Documentacion del Caso: Donde un cliente necesitamos ejecutar un procedimiento almacenado que esta creado en ORACLE, por lo que hemos podido revisar ORACLE automaticamente inicia una transaccion y considero que esa es la razon por la cual nos genera el siguiente error:

2017-07-19 12:04:39,556 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Inicia la ejecución de la finalización: f9d0344a-3f74-49fc-af14-3f964825a0eb
2017-07-19 12:04:39,571 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Reconfigurando el contenedor de Unity para la finalización: f9d0344a-3f74-49fc-af14-3f964825a0eb
2017-07-19 12:04:39,571 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Inicializando el MetadataService para ejecutar la finalización: f9d0344a-3f74-49fc-af14-3f964825a0eb
2017-07-19 12:04:39,821 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Obteniendo el servicio [Aseinfo.VH4.Acciones.Base.Contrataciones.IContratacionService] para ejecutar la finalización: f9d0344a-3f74-49fc-af14-3f964825a0eb
2017-07-19 12:04:39,853 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Iniciando la transacción para la finalización: f9d0344a-3f74-49fc-af14-3f964825a0eb
2017-07-19 12:04:39,868 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Construyendo objeto bitácora de ejecución de proceso f9d0344a-3f74-49fc-af14-3f964825a0eb
2017-07-19 12:04:39,868 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Finalización f9d0344a-3f74-49fc-af14-3f964825a0eb -- Ejecutando VALIDACION en el Servicio ...
2017-07-19 12:04:39,884 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Finalización f9d0344a-3f74-49fc-af14-3f964825a0eb -- Ejecutando FINALIZACION en el Servicio ...
2017-07-19 12:04:40,009 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Finalización f9d0344a-3f74-49fc-af14-3f964825a0eb -- Ejecutanto procedimiento DESPUES: acc.finaliza_contratacion ...
2017-07-19 12:04:40,087 [AppJobWinServiceScheduler_Worker-9] ERROR Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Mensaje de Validación al ejecutar la finalización f9d0344a-3f74-49fc-af14-3f964825a0eb
**Aseinfo.Infrastructure.Base.Exceptions.AseinfoException: 
ERROR_CODE: 7391;  
DESCRIPCION: The operation could not be performed because OLE DB provider "OraOLEDB.Oracle" for linked server "TCBPGT" was unable to begin a distributed transaction.
Uncommittable transaction is detected at the end of the batch. The transaction is rolled back.
OLE DB provider "OraOLEDB.Oracle" for linked server "TCBPGT" returned message "New transaction cannot enlist in the specified transaction coordinator. ". 
---> System.Data.SqlClient.SqlException: 
ERROR_CODE: 7391;  
DESCRIPCION: The operation could not be performed because OLE DB provider "OraOLEDB.Oracle" for linked server "TCBPGT" was unable to begin a distributed transaction.
Uncommittable transaction is detected at the end of the batch. The transaction is rolled back.
OLE DB provider "OraOLEDB.Oracle" for linked server "TCBPGT" returned message "New transaction cannot enlist in the specified transaction coordinator. ".**
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at Microsoft.Practices.EnterpriseLibrary.Data.Database.DoExecuteNonQuery(DbCommand command)
   at Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery(DbCommand command)
   at Aseinfo.Infrastructure.Repositories.DbDataAccessRepository.EjecucionProcedimientoAlmacenado(String storedProcedureName, IDictionary`2 valoresParametros, IDictionary`2& outputParameters) in C:\vh4\Infrastructure\Data\DbDataAccessRepository.cs:line 907
   at Aseinfo.Infrastructure.Repositories.DbDataAccessRepository.ExecuteNonQueryStoredProcedure(String storedProcedureName, IDictionary`2 valoresParametros) in C:\vh4\Infrastructure\Data\DbDataAccessRepository.cs:line 741
   at Aseinfo.Infrastructure.Base.Entity.EntityServiceBase`2.EjecutarProcedimientoFinalizar(IDictionary`2 entityKeyValues, String nombreProcedimiento) in C:\vh4\Infrastructure\Base\Entity\EntityServiceBase.cs:line 1099
   at Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob.Execute(JobExecutionContext context) in C:\VH4\VH4\WindowsServices\ApplicationJobsWindowsService\ApplicationJobs\AccionFinalizacionJob.cs:line 357
   --- End of inner exception stack trace ---
   at Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob.Execute(JobExecutionContext context) in C:\VH4\VH4\WindowsServices\ApplicationJobsWindowsService\ApplicationJobs\AccionFinalizacionJob.cs:line 362
2017-07-19 12:04:40,118 [AppJobWinServiceScheduler_Worker-9] INFO  Aseinfo.VH4.WindowsServices.ApplicationJobs.AccionFinalizacionJob - Iniciando la programación del reintento dentro de un minuto proceso [Aseinfo.VH4.Acciones.Base.Contrataciones.IContratacionService] para ejecutar la finalización: f9d0344a-3f74-49fc-af14-3f964825a0eb

O si tienen alguna sugerencia para solventar este incidente favor de hacermelo saber.

asked 19 Jul '17, 13:02

Luis%20Armas's gravatar image

Luis Armas
(suspended)
accept rate: 8%

edited 21 Jul '17, 10:15

Fernando%20Paz's gravatar image

Fernando Paz ♦♦
17.3k81635


Gracias por sus respuestas, Las opciones de JOB y/o Alertas o Ejecucion de Procedimiento Almacenado ya las habia considerado anteriormente, más sin embargo no me he decidido por ellas porque el Proceso a ejecutar necesita actualizar datos del lado del ORACLE, que a su vez retornara un estatus de proceso satisfactorio o no, por tal razón lo necesitamos en vivo. Si fallase dicho proceso del lado del oracle, pues no procedería para este caso la contratación del lado de Evolution.

Si como me indican no es posible evitar la transaccion interna que genera Evolution, pues buscaremos alternativas como por ejemplo consumo WEB Service.

Saludos.

link

answered 21 Jul '17, 11:37

Luis%20Armas's gravatar image

Luis Armas
(suspended)
accept rate: 8%

Podes utilizar CLR y generar dlls para consumir Web Service desde la base de datos, si necesitas documentación te la puedo pasar.

(21 Jul '17, 11:48) William Guevara William%20Guevara's gravatar image

La opción con CLR es cómoda, pero se necesita habilitar el SQL Server para se puedan ejecutar.

Si la llamada no es muy compleja, se puede con T-SQL usando un método que sobrevive desde las versiones antiguas de SQL Server.

https://stackoverflow.com/questions/33449/can-you-call-a-webservice-from-tsql-code

Otra manera es con un 'Web Service Task' de 'SQL Integration Services'

https://docs.microsoft.com/en-us/sql/integration-services/control-flow/web-service-task

(21 Jul '17, 18:36) Fernando Paz ♦♦ Fernando%20Paz's gravatar image

Lamentablemente, no es posible eliminar la transacción del código fuente, ya que esta transacción garantiza la atomicidad de todas las operaciones a realizar; las cuales involucran el código que se ejecuta en el fuente, el procedimiento de antes y despues de la finalización, la generación de la bitácora y la notificación del resutado.

Veo que la causa del problema es que el procedimiento de finalización acc.finaliza_contratacion está ejecutando instrucciones con un Linked Server a una base de datos Oracle.

Las transacciones distribuidas entre bases de datos diferentes (de cualquier marca), como la que estás queriendo hacer, son complicadas y requieren trabajo de configuración a nivel de servidores y servicios, y una redacción especial de los querys, del lado de SQL Server y de Oracle.

Esto también ocurre si se trata de escribir en otra base SQL Server (conectada con un Linked Server)

Te dejo algunos links, donde se habla de este problema:

Scripting a distributed transaction on SQL

Oracle Transactions Support with MS DTC

Using Microsoft Transaction Server with Oracle Database

BEGIN DISTRIBUTED TRANSACTION (Transact-SQL)

Toda esta documentación es compleja de aplicar y pudiera requerir mucha inversión en tiempo y esfuerzo. Por lo que mi sugerencia es que envíen la información a Oracle, de una manera diferente. De manera asincrónica, para evitar que la llamada a Oracle se haga desde el procedimiento de finalización.

Para ello podes explorar muchas técnicas, por ejemplo:

  • Crear un Job de base de datos en SQL Server o una Alerta de Evolution, que este constantemente evaluando si hay información que se debe enviar a la base Oracle. De esta manera la ejecución del procedimiento controla la creación de la transacción.
  • Elaborar el interfaz desde la otra vía. Es decir que sea Oracle el que tenga configurado el DBLINK a SQL Server y que esté constantemente evaluando si necesita traer información de Evolution.

También, es aconsejable eliminar las transacciones de los procedimentos de base, de tal manera que quede únicamente la transacción del código fuente, para que sea más facil llegar a la configuración correcta entre los servidores. Primero, porque la atomicidad de la transacción es garantizada por la infraestructura del MTS y del DTC. En segundo lugar, porque siempre es posible redactar el proceso validando las operaciones antes de realizarlas, para retornar los errores al código fuente de Evolution y que sea él quien cancele la transacción global.

link

answered 21 Jul '17, 10:36

Fernando%20Paz's gravatar image

Fernando Paz ♦♦
17.3k81635
accept rate: 51%

Intenta configurar el DTC de manera idéntica en ambos lados y configurar en el linked server: Enable Promotion of Distributed Transactions: True.

Si no funciona, eso que te digo, como lo dijo Fernando, podes crear un Job sin schedule, y ejecutarlo a través de un procedimiento almancenado. ESTE ES UN EJEMPLO:

/*INICIO DEL SCRIPT DEL JOB*/

declare @codcia int, @usuario varchar(50), @codcdt int, @codigo int

select @codigo = max(codigo) 
from xxxx.parametros_EJECUCIONJOB

select @codcia = codcia,
    @usuario = usuario,
    @codcdt = codcdt
from xxxx.parametros_EJECUCIONJOB 
where codigo = @codigo

---EN ESTE SEGMENTO COLOCAS LO QUE REALMENTE QUERES EJECUTAR
EXECUTE xxxx.PROCEDIMIENTOAEJECUTAR @codcia,@usuario,@codcdt

/*FIN DEL SCRIPT DEL JOB*/

/*CUERPO DEL PROCEDIMIENTO ALMACENADO QUE SE EJECUTA DESDE EVOLUTION PARA INVOCAR EL JOB*/

create procedure [XXXX].[Sub_EjecutaJobXXXX]
    @codcia int,
    @usuario varchar(100),
    @codcdt int
as

insert into XXXX.parametros_EJECUCIONJOB (codcia,usuario,codcdt,fecha_generacion)
select @codcia, @usuario,@codcdt, getdate()

declare @output_flag int

EXEC msdb.dbo.sp_start_job 
        @job_name =  N'NOMBREDELJOBAEJECUTAR',
        @output_flag = null

declare @msg varchar(4000)

if @output_flag != 0 begin
    set @msg  = 'El proceso no se pudo ejecutar.'
    raiserror(@msg,16,1 )
    return
end

declare @inicio datetime, @sesion int, @inicio_sesion datetime
set @inicio = getdate()

SELECT @inicio_sesion = MAX(agent_start_date ) 
  FROM msdb.dbo.syssessions

while EXISTS(
            SELECT job.name, 
                   job.job_id, 
                   job.originating_server, 
                   activity.run_requested_date, 
                   DATEDIFF( SECOND, activity.run_requested_date, GETDATE() ) as Elapsed
              FROM msdb.dbo.sysjobs_view job
              JOIN msdb.dbo.sysjobactivity activity
                ON job.job_id = activity.job_id
              JOIN msdb.dbo.syssessions sess
                ON sess.session_id = activity.session_id
             WHERE run_requested_date IS NOT NULL 
               AND stop_execution_date IS NULL
               and sess.agent_start_date = @inicio_sesion
               and job.name = 'NOMBREDELJOBAEJECUTAR'
         )
         and
          /* TIEMPO LIMITE PARA LA EJECUCION, CADA 5 SEGUNDOS SE EVALUA SI LA EJECUCION YA TERMINO*/
         datediff(mi,@inicio,getdate()) < 60*2 
         begin
    WAITFOR DELAY '00:00:05'
    CONTINUE
end

if datediff(mi,@inicio,getdate()) >60*2 begin
   set @msg  = 'El proceso tarda mas de '+cast(60*2 as varchar)+' minutos por lo que fue cancelado.'
   raiserror(@msg,16,1 )
   return
end

/**FIN  DEL PROCEDIMIENTO*/
link

answered 21 Jul '17, 11:23

Julio%20Flores's gravatar image

Julio Flores
(suspended)
accept rate: 42%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Evolution en BitBucket

En este sitio puede acceder al código fuente, centro de descargas y reportar bugs, propuestas y mejoras para Evolution.

Evolution en JIRA

En este sitio puedes sugerir nueva funcionalidad para Evolution, o puedes votar por la funcionalidad ya propuesta por otros usuarios.

Tags:

×1

Asked: 19 Jul '17, 13:02

Seen: 1,759 times

Last updated: 21 Jul '17, 18:38

Related questions

[Acerca de] [Preguntas Frecuentes] [Privacidad] [Soporte] [Contacto]
Copyright 2013-2018. Asesores en Informática