Principales respuestas
SERVIDORES VINCULADOS

Pregunta
-
Que tal, espero puedan ayudarme estoy usando servidores vinculados para acceder a una BD de otro servidor, el manejo de transacciones lo hago desde la aplicación dentro de la cual invoco a un procedimiento almacenado que en primera instancia actualizaba datos de las tablas del servidor local y tablas del servidor vinculado como se detalla a continuación:
--inserción en servidor local
insert into alumno (id_alumno,alu_periodo,id_empresa,id_distrito,alu_ nombres,alu_apellidos,
alu_direccion,alu_telefono,alu_fec_nacimiento,alu_ lib_electoral,
alu_centro_estudio,alu_categoria,alu_estado,alu_cl iente,alu_sexo,alu_fecha,
alu_mac,alu_correo_ele,alu_celular)
values (@codigo_alu,@periodo,@emp,@distri,@nombre,@apell, @direc,
@telef,@fecnan,@dni,@cest,NULL,
@est,@id_cliente,@sexo, @fecha, @mac, @corr,@celu)
--inserción en servidor vinculado
insert into CAMPUS_SISE_VINCULADO.CAMPUS_SISE.dbo.alumno
(id_alumno,id_local,alu_periodo,id_empresa,id_dist rito,alu_nombres,
alu_apellidos,alu_direccion,alu_telefono,alu_fec_n acimiento,alu_lib_electoral,
alu_centro_estudio,alu_categoria,alu_estado,alu_cl iente,alu_sexo,alu_fecha,
alu_mac,alu_correo_ele,alu_celular)
values (@alumno,@centro_lucro,@periodo,@emp,@distri,@nomb re,@apell,@direc,
@telef,@fecnan,@dni,@cest,NULL,@est,@id_cliente,@s exo,@fecha,@mac,
@corr,@celu)
Pero al ejecutar el procedimiento desde la aplicación me generaba error indicando que se debe usar transacciones distribuídas por lo que no me quedó otra opción que trabajarlo en 2 procedimientos separados uno para la actualización local y otro para la actualización del servidor vinculado, el manejo de transacciones se realiza en el servidor local desde la aplicación.
Hasta allí no tenía problemas, pero estoy verificando que en algunas ocasiones algunos registros se actualizan en el servidor local pero no en el servidor remoto.
No se si esto se deba a que no trabajo todo en una sola transacción, teniendo en cuenta que varios usuarios pueden ejecutar el proceso al mismo tiempo.
Espero me puedan...
Respuestas
-
Hola.Efectivamente, debes realizar los dos pasos en la misma transacción (que debe ser una transacción distribuida) para asegurarte de que se hacen las dos inserciones o ninguna. Has de tener el servicio MSDTC arrancado en ambos servidores para que se pueda completar esa transacción distribuida. Puedes hacerlo en un sólo procedimiento almacenado o en dos, eso ya como veas, pero en la misma transacción.Alberto López Grande.
- Propuesto como respuesta Alberto López Grande (qwalgrande)Moderator miércoles, 1 de abril de 2009 18:10
- Marcado como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 21:41
-
Lo puedes lograr a nivel de transact-sql la sintaxis seria algo como la siguiente
USE AdventureWorks; GO BEGIN DISTRIBUTED TRANSACTION; -- Delete candidate from local instance. DELETE AdventureWorks.HumanResources.JobCandidate WHERE JobCandidateID = 13; -- Delete candidate from remote instance. DELETE RemoteServer.AdventureWorks.HumanResources.JobCandidate WHERE JobCandidateID = 13; COMMIT TRANSACTION; GO
Recuerda que el servicio de MSDTC debe estar habilitado en ambos servidores como lo dice Alberto,
Saludos
Andrés González MCITP | Business Intelligence Developer - MCPD | Web Developer http://www.intermezzo-bi.com- Editado Carlos Andres Gonzalez [BogotaDotNet.Org] miércoles, 1 de abril de 2009 19:58 ortografia
- Propuesto como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] miércoles, 1 de abril de 2009 19:59
- Marcado como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 21:41
-
Hola Hans hay un articulo en ayuda y soporte de microsoft con el error que reportas revisalo y nos cuentas si es tu escenario y de ser asi como te fue
http://support.microsoft.com/kb/839279/es
Andrés González MCITP | Business Intelligence Developer - MCPD | Web Developer http://www.intermezzo-bi.com- Propuesto como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 4:52
- Editado Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 5:25 ortografia
- Marcado como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 21:41
-
Bueno me contesto a mi mismo, le active la opción XACT_ABORT a ON y con ello se solucionó el inconveniente, estando en ON te garantiza que si hay un error en el proceso se desactive la transacción, este es el script correcto:
SET XACT_ABORT ONBEGIN DISTRIBUTED TRANSACTION;
-- Delete candidate from local instance.
DELETE actividades
-- Delete candidate from remote instance.
DELETE CAMPUS_SISE_VINCULADO.CAMPUS_SISE.dbo.pagos_alumnoCOMMIT TRANSACTION;
SET XACT_ABORT OFF
Espero le sirva a alguien mas...- Marcado como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 21:41
Todas las respuestas
-
Hola.Efectivamente, debes realizar los dos pasos en la misma transacción (que debe ser una transacción distribuida) para asegurarte de que se hacen las dos inserciones o ninguna. Has de tener el servicio MSDTC arrancado en ambos servidores para que se pueda completar esa transacción distribuida. Puedes hacerlo en un sólo procedimiento almacenado o en dos, eso ya como veas, pero en la misma transacción.Alberto López Grande.
- Propuesto como respuesta Alberto López Grande (qwalgrande)Moderator miércoles, 1 de abril de 2009 18:10
- Marcado como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 21:41
-
-
Lo puedes lograr a nivel de transact-sql la sintaxis seria algo como la siguiente
USE AdventureWorks; GO BEGIN DISTRIBUTED TRANSACTION; -- Delete candidate from local instance. DELETE AdventureWorks.HumanResources.JobCandidate WHERE JobCandidateID = 13; -- Delete candidate from remote instance. DELETE RemoteServer.AdventureWorks.HumanResources.JobCandidate WHERE JobCandidateID = 13; COMMIT TRANSACTION; GO
Recuerda que el servicio de MSDTC debe estar habilitado en ambos servidores como lo dice Alberto,
Saludos
Andrés González MCITP | Business Intelligence Developer - MCPD | Web Developer http://www.intermezzo-bi.com- Editado Carlos Andres Gonzalez [BogotaDotNet.Org] miércoles, 1 de abril de 2009 19:58 ortografia
- Propuesto como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] miércoles, 1 de abril de 2009 19:59
- Marcado como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 21:41
-
Hola.Eso ya depende de cómo gestiones las transacciones en general, ya que lo puedes hacer en los dos puntos. Yo lo haría a nivel de base de datos porque me siento más cómodo en esa parte, aunque las dos opciones mejores serían realizarlo en un único procedimiento almacenado con control de transacciones (distribuidas, claro) o hacerlo con dos procedimientos almacenados, desde la aplicación, pero cada uno de ellos local, con dos conexiones y sin tener que usar servidores vinculados. Lo que no tiene sentido es hacerlo desde aplicación y usar servidores vinculados.Alberto López Grande.
- Propuesto como respuesta Alberto López Grande (qwalgrande)Moderator miércoles, 1 de abril de 2009 21:01
-
Hola en realidad no tengo mucho conocimiento de como gestiona las conexiones delphi, pero en .net se levanta una transaccion por cada objeto sqlconnection que tienes, entonces no veria como podrias hacerlo a nivel de aplicacion, ya que tendrias un objeto conexion por cada base de datos que interfiere en tu proceso, lo que implica que tendrias dos transacciones independientes.
Partiendo de esto solo lo veria a nivel de Transact-SQL
Saludos
Andrés González MCITP | Business Intelligence Developer - MCPD | Web Developer http://www.intermezzo-bi.com -
-
Que tal, cuando pruebo usar la transacción distribuída desde el Transact SQL me sale este mensaje:
No se puede realizar la operación. El proveedor OLE DB 'SQLOLEDB' no pudo iniciar una transacción distribuida.
[OLE/DB provider returned message: No se puede dar de alta la nueva transacción en el coordinador de transacciones especificado. ]
Traza de error de OLE DB [OLE/DB Provider 'SQLOLEDB' ITransactionJoin::JoinTransaction returned 0x8004d00a].
Este es el procedimiento que estoy ejecutando:
------------------
create procedure dbo.pruebaas
BEGIN DISTRIBUTED TRANSACTION;
-- Delete candidate from local instance.
DELETE actividades
-- Delete candidate from remote instance.
DELETE CAMPUS_SISE_VINCULADO.CAMPUS_SISE.dbo.pagos_alumnoCOMMIT TRANSACTION;
---------------------
El problema me sale cuando trato de borrar la tabla pagos_alumno del servidor vinculado
El coordinador de transacciones distribuídas esta activo en ambos servidores.
Gracias por la atención.
Hans Vallejos H. -
Hola Hans hay un articulo en ayuda y soporte de microsoft con el error que reportas revisalo y nos cuentas si es tu escenario y de ser asi como te fue
http://support.microsoft.com/kb/839279/es
Andrés González MCITP | Business Intelligence Developer - MCPD | Web Developer http://www.intermezzo-bi.com- Propuesto como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 4:52
- Editado Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 5:25 ortografia
- Marcado como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 21:41
-
Hola a todos, se ha realizado los pasos indicados en el artículo de ayuda y soporte de microsoft porque los 2 servidores están sobre Windows 2003 Server y al momento de probar las transacciones me sale otro error que adjunto:
No se puede iniciar una transacción anidada para el proveedor OLE DB 'SQLOLEDB'. Es necesaria una transacción anidada porque la opción XACT_ABORT era OFF.
[OLE/DB provider returned message: No se pueden iniciar más transacciones en esta sesión.]
Traza de error de OLE DB [OLE/DB Provider 'SQLOLEDB' ITransactionLocal::StartTransaction returned 0x8004d013: ISOLEVEL=4096]. -
Hola Hans prueba lo siguiente al ejecutar el procedimiento almacenado donde se encuentra la transaccion distribuida
SET XACT_ABORT ON;
EXEC [my_stored_proc]
SET XACT_ABORT OFF;
Espero te funcione saludos
Andrés González MCITP | Business Intelligence Developer - MCPD | Web Developer http://www.intermezzo-bi.com- Propuesto como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 19:33
-
Bueno me contesto a mi mismo, le active la opción XACT_ABORT a ON y con ello se solucionó el inconveniente, estando en ON te garantiza que si hay un error en el proceso se desactive la transacción, este es el script correcto:
SET XACT_ABORT ONBEGIN DISTRIBUTED TRANSACTION;
-- Delete candidate from local instance.
DELETE actividades
-- Delete candidate from remote instance.
DELETE CAMPUS_SISE_VINCULADO.CAMPUS_SISE.dbo.pagos_alumnoCOMMIT TRANSACTION;
SET XACT_ABORT OFF
Espero le sirva a alguien mas...- Marcado como respuesta Carlos Andres Gonzalez [BogotaDotNet.Org] jueves, 2 de abril de 2009 21:41
-