Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    octobre 2018
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : octobre 2018
    Messages : 55
    Points : 40
    Points
    40

    Par défaut Explication service borker

    Bonjour,
    Après quelques recherches sur google, je vois que c'est impossible de faire une transaction entre deux bases de données sans passer par le coordinateur de transaction ou par service broker.
    Aussi j'ai lu (si je me trompe pas) est que service broker est plus intéressant à utiliser mais je trouve pas comment l'utiliser... ci dessous la problématique que j'ai :
    Je dois récupérer des ensembles de factures d'une base de données Sage vers une autre base de données (les deux bases sont sur la même instance SQL), je dois flaguer les factures sur Sage une fois que leur importation est faite avec succès.
    La base Sage interdit la modification d'un enregistrement si ce dernier(à l'aide d'un trigger et une fonction scalaire) est ouvert en mode consultation par un utilisateur
    le code de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    CREATE FUNCTION [dbo].[CB_FntIsRecordLock]
    (@cbFile SYSNAME, 
     @cbMarq AS INT
    )
    RETURNS INT
    AS
         BEGIN
             DECLARE @lBase INT, @lTable INT, @lRes INT;
             SET @lBase = DB_ID();
             SET @lTable = OBJECT_ID(@cbFile);
             EXECUTE master..xp_CBIsRecordLock 
                     @@SPID, 
                     @lBase, 
                     @lTable, 
                     @cbMarq, 
                     @lRes OUTPUT;
             RETURN @lRes;
         END;
    GO
    le trigger :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
     
    CREATE TRIGGER [dbo].[TG_CBUPD_F_DOCREGL] ON [dbo].[F_DOCREGL] FOR UPDATE AS 
    BEGIN
    	DECLARE @sGUID uniqueidentifier;
     
    	BEGIN TRY
    		SET NOCOUNT ON;
    		IF dbo.CB_FntIsFileLock('F_DOCREGL',3) = 1 
    			Raiserror(80004,11,1);
    		IF dbo.CB_FntIsFileLock('F_DOCREGL',0) = 1 
    			Raiserror(80008,11,1);
    		IF dbo.CB_FntIsFileLock('F_DOCREGL',1) = 1 
    			Raiserror(80008,11,1);
    		IF EXISTS(SELECT 'a' FROM inserted where dbo.CB_FntIsRecordLock('F_DOCREGL',cbMarq) = 1)
    			Raiserror(80003,11,1);
    		IF EXISTS(SELECT 'a' FROM cbUserSession WHERE cbSession != @@SPID AND cbCurrentSynchroType != 0 AND CB_Type = 'CIAL')
    			Raiserror(80012,11,1);
    		IF NOT UPDATE(cbModification) AND UPDATE(cbReplication) 
    			UPDATE F_DOCREGL SET cbModification = convert(datetime2(0) , GetDate()),cbReplication = inserted.cbReplication FROM inserted WHERE F_DOCREGL.cbMarq = inserted.cbMarq;
    		IF NOT UPDATE(cbReplication) AND UPDATE(cbModification) 
    			UPDATE F_DOCREGL SET cbModification = inserted.cbModification,cbReplication = (SELECT ISNULL(CB_Replication,0) FROM cbSysTable WHERE CB_Type = 'CIAL') FROM inserted WHERE F_DOCREGL.cbMarq = inserted.cbMarq;
    		IF NOT UPDATE(cbReplication) AND NOT UPDATE(cbModification) 
    			UPDATE F_DOCREGL SET cbModification = convert(datetime2(0) , GetDate()),cbReplication = (SELECT ISNULL(CB_Replication,0) FROM cbSysTable WHERE CB_Type = 'CIAL') FROM inserted WHERE F_DOCREGL.cbMarq = inserted.cbMarq;
    		IF UPDATE(cbFlag)
    		BEGIN
    			DELETE FROM cbSysLogRecord FROM cbSysLogRecord JOIN inserted ON (inserted.cbFlag & 1) = 0 AND cbSysLogRecord.cbMarq = inserted.cbMarq WHERE cbFile = 'F_DOCREGL';
    			IF NOT UPDATE(cbReplication)
    			BEGIN
    				IF (SELECT COUNT(*) FROM inserted JOIN deleted ON (deleted.cbFlag & 1) <> 1 AND deleted.cbMarq = inserted.cbMarq WHERE (inserted.cbFlag & 1) = 1) > 0
    				BEGIN
    					SELECT @sGUID = CB_LocalGUID FROM cbSysTable WHERE CB_Type = 'CIAL';
    					INSERT cbSysLogRecord (CB_Operation,CB_DateOperation,CB_Creator,CB_SiteOrigine,CB_Replication,CB_Identifiant,cbMarq,cbFile) SELECT 1,GetDate(),inserted.cbCreateur,@sGUID,inserted.cbReplication,NEWID(),inserted.cbMarq,'F_DOCREGL' FROM inserted JOIN deleted ON (deleted.cbFlag & 1) <> 1 AND deleted.cbMarq = inserted.cbMarq WHERE (inserted.cbFlag & 1) = 1 AND NOT EXISTS(SELECT 'a' FROM cbSysLogRecord WHERE cbFile = 'F_DOCREGL' AND cbSysLogRecord.cbMarq = inserted.cbMarq);
    				END;
    			END;
    		END
    		ELSE
    		BEGIN
    			IF (SELECT COUNT(*) FROM inserted WHERE (cbFlag & 1) = 1) > 0
    			BEGIN
    				SELECT @sGUID = CB_LocalGUID FROM cbSysTable WHERE CB_Type = 'CIAL';
    				UPDATE cbSysLogRecord SET CB_Operation = 2,CB_DateOperation = GetDate(),CB_Creator = inserted.cbCreateur,CB_Replication = inserted.cbReplication,CB_SiteOrigine = @sGUID FROM inserted WHERE cbFile = 'F_DOCREGL' AND cbSysLogRecord.cbMarq = inserted.cbMarq AND (inserted.cbFlag & 1) = 1;
    			END;
    		END;
    		IF UPDATE(DR_No)
    			IF (select count(*) FROM inserted JOIN deleted ON not deleted.DR_No is null and deleted.DR_No <> 0 and inserted.DR_No <> deleted.DR_No and inserted.cbMarq = deleted.cbMarq) > 0
    				Raiserror(80011,11,1);
    		IF UPDATE(EC_No)
    			UPDATE F_DOCREGL SET cbEC_No = NULLIF(inserted.EC_No,0) FROM inserted WHERE F_DOCREGL.cbMarq = inserted.cbMarq;
    		IF UPDATE(CA_No)
    			UPDATE F_DOCREGL SET cbCA_No = NULLIF(inserted.CA_No,0) FROM inserted WHERE F_DOCREGL.cbMarq = inserted.cbMarq;
    	END TRY
    	BEGIN CATCH
    		DECLARE
    			@ErrorMessage nvarchar(max),
    			@ErrorNumber int,
    			@ErrorSeverity int,
    			@ErrorState int;
     
    		SET @ErrorMessage = ERROR_MESSAGE();
    		SET @ErrorNumber = ERROR_NUMBER();
    		SET @ErrorSeverity = ERROR_SEVERITY();
    		SET @ErrorState = ERROR_STATE();
    		IF XACT_STATE() <> 0
    			ROLLBACK;
    		IF (@ErrorNumber = 1205) OR (@ErrorNumber = 1222)
    			RAISERROR(80008,@ErrorSeverity,@ErrorState);
    		ELSE
    		IF @ErrorNumber > 50000
    			RAISERROR(@ErrorNumber,@ErrorSeverity,@ErrorState);
    		ELSE
    			RAISERROR(@ErrorMessage,@ErrorSeverity,@ErrorState);
    		RETURN;
    	END CATCH;
    END;
    GO
    Norlament la ligne du trigger qui fait le test est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF EXISTS(SELECT 'a' FROM inserted where dbo.CB_FntIsRecordLock('F_DOCREGL',cbMarq) = 1)
    			Raiserror(80003,11,1);
    Donc si le trigger bloque mon update je doit annuler l'insertion dans la base cible (chose qui est impossible de le faire via service broker si j'ai bien compris) alors je sais pas comment je doit faire

    Merci de me corriger si je me trompe

    Merci

  2. #2
    Membre éclairé
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    septembre 2016
    Messages
    404
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : septembre 2016
    Messages : 404
    Points : 728
    Points
    728

    Par défaut

    Citation Envoyé par erpWorld Voir le message
    Après quelques recherches sur google, je vois que c'est impossible de faire une transaction entre deux bases de données sans passer par le coordinateur de transaction ou par service broker.
    C'est vrai dans le cadre des instances distantes.
    Dans ce cas un serveur lié est une bonne chose, le service Distributed Transaction Coordinator (DTC ou MSDTC) démarré sur le serveur qui déclare le serveur lié et indiquer qu'il s'aggit d'une transaction distribué (BEGIN DISTRIBUTED TRANSACTION).

    Dans le cadre des bases hébergées par la même instance c'est plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    create database DB1;
    create database DB2;
     
    create table db1.dbo.T1 (col1 int)
    create table db2.dbo.T1 (col1 int)
     
    /* rollback programmé */
    begin transaction
        insert into db1.dbo.T1 values (1);
        insert into db2.dbo.T1 values (1);
    rollback
    select * from db1.dbo.T1
    select * from db2.dbo.T1
     
    /*commit programmé */
    begin transaction
        insert into db1.dbo.T1 values (1);
        insert into db2.dbo.T1 values (1);
    commit
    select * from db1.dbo.T1
    select * from db2.dbo.T1
     
    /* commit programmé mais erreur */
    begin transaction
        insert into db1.dbo.T1 values (1);
        insert into db2.dbo.T1 values ('toto');
    commit
    go
    select * from db1.dbo.T1
    select * from db2.dbo.T1
    Je dois récupérer des ensembles de factures d'une base de données Sage vers une autre base de données (les deux bases sont sur la même instance SQL), je dois flaguer les factures sur Sage une fois que leur importation est faite avec succès.
    La base Sage interdit la modification d'un enregistrement si ce dernier(à l'aide d'un trigger et une fonction scalaire) est ouvert en mode consultation par un utilisateur
    En commençant par faire un update de test dans Sage avant de faire l'export évitera d'avoir à faire un rollback trop lourd.

    Je verrais bien au moins 3 états au flag d'export :
    * export pas fait
    * export en préparation
    * export fait
    Si le flag est une date alors {NULL, '19000101', date du jour}

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/06/2015, 15h13
  2. [2.x] Explication : Bundle, Service et Configuration
    Par rebolon dans le forum Symfony
    Réponses: 2
    Dernier message: 17/11/2011, 11h21
  3. Windows Phone 7 - explication service web
    Par toss.net dans le forum Windows Phone
    Réponses: 20
    Dernier message: 28/10/2010, 07h29
  4. Demande d'explications sur certains services
    Par Gunner4902 dans le forum Windows XP
    Réponses: 2
    Dernier message: 26/10/2008, 23h19
  5. Service de nommage java C++
    Par Anonymous dans le forum CORBA
    Réponses: 3
    Dernier message: 15/04/2002, 12h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo