Réplication vers une base sybase RTDS, gestion du paramètre 'transactional messaging'

Logo

Introduction

Dans une configuration Replication Server vers une base de données Sybase mettant en œuvre Real Time Data Services, on souhaite garantir la cohérence entre l’envoi des messages vers MQ (ou TIBCO) et les transactions SQL et plus particulièrement en cas d’échec.

À titre d’exemple : le message vers MQ ne doit pas partir si une commande SQL est en échec et que la transaction est annulée.

Cet article rappelle le mode transactionnel avec Sybase RTDS et décrit techniquement ce qui doit être mis en œuvre pour assurer la cohérence dans un environnement Replication Server. La méthode consiste à créer une classe de fonctions Replication Server personnalisée afin de surcharger la chaîne fonction système rs_usedb (function string).

La définition des classes de fonctions personnalisées pour surcharger des chaînes fonction (function strings) est disponible dans le guide pratique Sybase Replication Server - §6 : Sybase Replication Server - Guide pratique, aide-mémoire

Rappels sur les transactions SQL et RTDS

Par défaut, toutes les opérations de messaging (msgsend, msgrecv, etc.) sont annulées si la transaction SQL est annulée. Toutefois une opération de messaging en échec n’affecte pas la transaction SQL parente.

Le comportement transactionnel est contrôlé par la commande T-SQL « set transactionnal messaging ».

set transactional messaging [ none | simple | full ]

Par défaut , le mode est simple dans une session T-SQL. Il s’agit d’une option qui n’existe qu’au niveau de la session et qui n’existe pas au niveau du serveur (option non existante avec sp_configure), par ailleurs il est impossible d’appliquer la commande set transactional messaging au sein d’une transaction.

Le mode 'none'

Dans le mode none, les opérations de messaging et bases de données n’intéragissent pas.

set transactional messaging none
begin tran
select msgsend(...)
insert (...)

La commande msgsend est exécutée que l’insertion échoue ou pas et vice versa.

Le mode 'simple'

Dans le mode simple, mode par défaut dans une session T-SQL, les opérations bases de données affectent les opérations de messaging, mais le contraire n’est pas vrai, les opérations de messaging n’ont aucune influence sur les opérations bases de données.

set transactional messaging simple
begin tran
select msgsend(...)
insert (...)

La commande insert n’est pas abandonnée si la commande msgsend échoue en revanche la commande msgsend est annulée si l’insertion échoue.

Le mode 'full'

Dans le mode full, les opérations bases de données affectent les opérations de messaging et vice-versa les opérations de messaging affectent les opérations bases de données.

set transactional messaging full
begin tran
select msgsend(...)
insert (...)

La commande insert est abandonnée si la commande msgsend échoue et la commande msgsend est annulée si l’insertion échoue.

Réplication vers une base de données Sybase RTDS

Le contexte est désormais le suivant : un serveur de réplication Sybase réplique vers une base Sybase qui s’appelle idee. Pour une table en particulier ID_XACT, un trigger T_ID_XACT_I est appliqué pour les insertions, trigger qui exécute une procédure stockée p_extract_M2E dans laquelle une commande msgsend est utilisée pour envoyer un message MQ.

schema replication Sybase ASE RTDS

Par défaut, lorsque la réplication se connecte à la base secondaire avec l’utilisateur de maintenance idee_maint, le paramètre de session transactional messaging est à simple.

Que le mode soit à simple est problèmatique, en effet le message est envoyé avec la commande select msgsend dans la procédure stockée même si la transaction est en échec. C’est le comportement par défaut du mode simple.

On souhaite que le paramètre de session transactional messaging soit à full lorsque la réplication se connecte à la base secondaire, pour cela, des replication server function strings doivent être mises en œuvre.

Création de la nouvelle classe de fonctions rtds_function_class

Pour encapsuler la fonction qui appliquera le mode full pour le paramètre de session transactional messaging, la classe de fonctions rtds_function_class héritant de la classe rs_default_function_class est créée avec la commande Replication Server create function string class.

Avant la création, il est préférable de s’assurer que cette dernière classe n’existe pas déjà avec la commande Replication Server admin show_function_classes

DEC_D1_REP> admin show_function_classes
DEC_D1_REP> go

Class                           ParentClass                     Level
------------------------------ ------------------------------- -----
rs_sqlserver_function_class     BASE_CLASS                      0
rs_asa_function_class           rs_default_function_class       1
rs_ims_function_class           rs_default_function_class       1
rs_informix_function_class      rs_default_function_class       1
rs_msss_function_class          rs_default_function_class       1
rs_oracle_function_class        rs_default_function_class       1
rs_udb_function_class           rs_default_function_class       1
rs_vsam_function_class          rs_default_function_class       1
rs_default_function_class       BASE_CLASS                      0
rs_db2_function_class           BASE_CLASS                      0

La classe de fonctions rtds_function_class héritant de rs_default_function_class est alors créée :

DEC_D1_REP> create function string class rtds_function_class
DEC_D1_REP> set parent to rs_default_function_class
DEC_D1_REP> go

Function string class 'rts_function_class' is created.
DEC_D1_REP> admin show_function_classes
DEC_D1_REP> go
          
Class                           ParentClass                     Level
------------------------------- ------------------------------- -----
rs_sqlserver_function_class     BASE_CLASS                      0
rtds_function_class             rs_default_function_class       1
rs_asa_function_class           rs_default_function_class       1
rs_ims_function_class           rs_default_function_class       1
rs_informix_function_class      rs_default_function_class       1
rs_msss_function_class          rs_default_function_class       1
rs_oracle_function_class        rs_default_function_class       1
rs_udb_function_class           rs_default_function_class       1
rs_vsam_function_class          rs_default_function_class       1
rs_default_function_class       BASE_CLASS                      0
rs_db2_function_class           BASE_CLASS                      0

Personnalisation de la fonction rs_usedb dans la classe rtds_function_class

La fonction standard rs_usedb de la classe rs_default_function_class permet de changer les contextes d’accès à une base de données dans un serveur Sybase par la réplication.

  • La fonction rs_usedb est exécutée par le DSI de Replication Server lorsque ce dernier ce connecte au serveur Sybase.
  • Replication Server créé une fonction rs_usedb système durant l’installation pour la classe par défaut rs_default_function_class.

C’est la fonction rs_usedb qu’il faut surcharger en appliquant la commande T-SQL set transactional messaging FULL afin que le DSI de Replication Server se connecte avec le paramètre de session transactional messaging positionné à FULL :

create function string rs_usedb 
for rtds_function_class
with overwrite output language
      'use ?rs_destination_db!sys_raw?;
           set transactional messaging FULL;
      '
go

Function string 'rs_usedb' is created.

Application de la classe de fonctions rtds_function_class aux connexions

Il ne reste plus qu’à appliquer la classe de fonctions rtds_function_class aux connexions DSI vers les bases de données pour lesquelles du RTDS est mis en œuvre, et dans ce contexte le DSI se connectera avec la commande set transactional messaging full grâce à la fonction personnalisée rs_usedb.

Pour appliquer la classe de fonctions à une connexion, la commande alter connection est utilisée :

alter connection to <DS>.<DB> set function string class <function_class>

À l’issue du changement, les commandes suspend connection / resume connection rendent effectives l’utilisation de la classe rtds_functionc_class.

Mise en pratique :

DEC_D1_ASE > alter connection to DEC_D2_ASE.idee set function string class rtds_function_class
DEC_D1_ASE > go

Connection to 'DEC_D2_ASE.idee' is altered.
DEC_D1_ASE > alter connection to DEC_T5_ASE.idee set function string class rtds_function_class
DEC_D1_ASE > go

Connection to 'DEC_T5_ASE.idee' is altered.
DEC_D1_ASE > suspend connection to DEC_D2_ASE.idee
DEC_D1_ASE > go

Connection to 'DEC_D2_ASE.idee' is suspended.
DEC_D1_ASE > suspend connection to DEC_T5_ASE.idee
DEC_D1_ASE > go

Connection to 'DEC_T5_ASE.idee' is suspended.
DEC_D1_ASE > resume connection to DEC_D2_ASE.idee
DEC_D1_ASE > go

Connection to 'DEC_D2_ASE.idee' is resumed.
DEC_D1_ASE > resume connection to DEC_T5_ASE.idee
DEC_D1_ASE > go

Connection to 'DEC_T5_ASE.idee' is resumed.

Vérifier avec dbcc pss que l’option est bien à FULL pour le paramètre de session 'transactional messaging'

Afin de vérifier le bon positionnement à FULL du paramètre de session transactional messaging pour la connexion du DSI dans le serveur ASE, la commande dbcc pss peut être utilisée.

Rappel de la syntaxe dbcc pss :

dbcc traceon(3604)
go
dbcc pss (suid, spid, 0)
go
  • suid : suid dans syslogins du login utilisé par le DSI de replication server pour se connecter (utilisateur de maintenance)
  • spid : process id de la connexion au DSI
  • L’option 0 dans dbcc pss nous suffira largement pour récupérer les informations de sessions que nous souhaitons.

En exécutant la commande dbcc pss dans le serveur DEC_D2_ASE :

DEC_D2_ASE > dbcc traceon(3604)
DEC_D2_ASE > go
DEC_D2_ASE > dbcc pss(15,130,0)
DEC_D2_ASE > go

Une section sur les options de sessions est très intéressante (la sortie est très verbeuse) :

      Sequencer Frame info in PSS :
      pprevframe=0x0 pnextframe=0x0 phdr=0x100065a4000
      pplan=0x100065a4000 pline=2 pcurstepno=2 prowcount=0

      poptions=7 (OPT_TRUNCABORT) 8 (OPT_ARITHABORT) 13 (OPT_CONTROL) 40 (OPT_PREFETCH) 41 (OPT_TRIGGERS) 42 (OPT_REPLICATION_1) 43 (OPT_REPLICATION_2) 48 (OPT_TRANSRPC) 58 (OPT_REMOTE_INDEXES) 62 (OPT_STMT_CACHE) 64 (OPT_PROC_RETURN_STATUS)
      65 (OPT_PROC_OUTPUT_PARAMS) 66 (OPT_XACTMESSAGING_1) 67 (OPT_XACTMESSAGING_2)
      pcurseq=0x0 pcurstep=0x0 plaststep=0x0 ptrigdata=0x0
      pprocedures=0x0 pview=0x0 pshareable=0x0 pbegintmps=0x0

Voici ce qui doit apparaître en fonction du paramètre de session transaction messaging

set transactional messagingValeur dbcc pss
none 66 (OPT_XACTMESSAGING_1)
simple /
full 66 (OPT_XACTMESSAGING_1) 67 (OPT_XACTMESSAGING_2)

Si l’on a bien 66 (OPT_XACTMESSAGING_1) 67 (OPT_XACTMESSAGING_2), le DSI de la réplication est bien connecté avec l’option FULL pour le paramètre de session transactional messaging.

Remarques importantes sur quelques paramètres de la réplication

Paramètre des connexions Replication Server : batch on

Dans l’exemple de cet article, la surcharge de la fonction rs_usedb est simple et ne comporte qu’une seule commande T-SQL :

create function string rs_usedb for msg_function_class
  with overwrite output language
  '
  use ?rs_destination_db!sys_raw?;
  set transactional messaging FULL;
  '

Si la surcharge des function strings contient plus d’une commande, le paramètre batch de la connexion au sein de Replication Server doit alors être positionné à on.

Par défaut ce paramètre est à on lorsqu’une connexion Replication Server vers une base de données est créée. Il est préférable de bien vérifier que le paramètre batch est à on. Pour appliquer ce paramètre :

Syntaxe :

alter connection to <dataserver>.<database> set batch to 'on'

Ce paramètre ne sera pris en compte qu’après une suspension/reprise de la connexion (suspend connection / resume connection).

Paramètre dsi_xact_group_size

Par défaut, Replication Server peut grouper plusieurs transactions en une seule. Pour éviter ce phénomène et si l’on souhaite s’assurer que l’envoi des messages RTDS soit associé à une transaction spécifique, le paramètre dsi_xact_group_size positionné à -1 sur une connexion Replication Server force Replication Server à ne pas grouper les transactions en une seule pour cette connexion :

Syntaxe :

alter connection to <dataserver>.<database> set dsi_xact_group_size to '-1'

Ce paramètre ne sera pris en compte qu’après une suspension/reprise de la connexion (suspend connection / resume connection).