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.
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éfautrs_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
danssyslogins
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 messaging | Valeur 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
).