Précédent   Forum des professionnels en informatique > Bases de données > Sybase
Sybase Forum sur la base de données Sybase. Avant de poster -> F.A.Q Sybase, Tutoriels Sybase
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/07/2006, 15h58   #1
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118
Par défaut [ASE] Erreur 941 - Illegal database context operation

Bonjour à tous.

Je m'essaye à écrire une proc stockée sur Sybase ASE 11.9 (je sais, ce n'est
plus maintenu !!)
La voici. C'est une proc qui renvoie des valeurs qui servent pour les clés
primaires numériques

Lorsque je l'execute via transact SQL je suis déconnecté et j'ai une
méchante erreur dans le log de Sybase: 941 - Illegal database context
operation

Comment faire pour la résoudre?
J'ai essayé la solution proposé ici mais rien à faire.
Merci de votre aide.

Abel

Erreur obtenue (extrait log du serveur)
Citation:
--------------------------------------------
00:00000:00010:2006/07/12 15:27:10.87 server Error: 941, Severity: 20, State: 1
00:00000:00010:2006/07/12 15:27:10.87 server Illegal database context operation.
00:00000:00010:2006/07/12 15:27:10.87 kernel ************************************
00:00000:00010:2006/07/12 15:27:10.87 kernel SQL causing error : DECLARE @i decimal
exec stpr_get_counter 'NAME',@i
SELECT @i
00:00000:00010:2006/07/12 15:27:10.87 kernel ************************************
00:00000:00010:2006/07/12 15:27:10.89 server SQL Text: DECLARE @i decimal
exec stpr_get_counter 'NAME',@i
SELECT @i
00:00000:00010:2006/07/12 15:27:10.89 kernel curdb = 5 pstat = 0x10000 lasterror = 941
00:00000:00010:2006/07/12 15:27:10.89 kernel preverror = 0 transtate = 0
00:00000:00010:2006/07/12 15:27:10.89 kernel curcmd = 224 program = SQL_Advantage
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x8a2977 os_get_cur_stk_desc+ 0x57 (0x13ff04c, 0x1d001d, 0x13ff04c, 0x0)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x8a2977 os_get_cur_stk_desc+ 0x57 (0x13ff04c, 0x13ff5a0, 0x270f, 0x2)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x883514 pcstkwalk+ 0x224 (0x1d001d, 0x2, 0x270f, 0x0)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x8830ae ucstkgentrace+ 0x1ce (0x0, 0x1, 0x14, 0x0)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x862864 ucbacktrace+ 0x84 (0x0, 0xffffffff, 0x13ff964, 0x4527a8)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x405fe6 terminate_process+ 0x566 (0x13ff9c4, 0x639a02, 0x9, 0x29)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x4527ea close_network+ 0x1a (0x9, 0x29, 0x14, 0x1)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x4527a8 hdl_default+ 0x48 (0x9, 0x29, 0x14, 0x1)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x639a02 s_handle+ 0x162 (0x9, 0x29, 0x14, 0x1)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x452413 ex_raise+ 0x193 (0xffffffff, 0x202d2594, 0x20010060, 0x0)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x47597c closedb+ 0x2ac (0x208192ac, 0x20819324, 0x0, 0x0)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x65a328 execproc+ 0x828 (0x202d2594, 0x81a, 0x2081edec, 0x0)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x65467a s_execute+ 0x213a (0x2080c800, 0x202d2594, 0x20010060, 0x0)
00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x6398a0 s_handle installed by the following function:-]
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x63678f sequencer+ 0x15f (0x2081ed74, 0x2081edec, 0x0, 0x0)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x659d8f execproc+ 0x28f (0x21, 0x202d2594, 0x202d2594, 0x20288e28)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x65467a s_execute+ 0x213a (0x2082d800, 0x21, 0x202d97d1, 0x202d2594)
00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x6398a0 s_handle installed by the following function:-]
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x63678f sequencer+ 0x15f (0x0, 0x20014b38, 0x1c001c, 0x20013830)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x436d31 tdsrecv_language+ 0xc1 (0x3, 0x4000, 0x20014b38, 0x1c001c)
00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x452660 hdl_backout installed by the following function:-]
00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x5c0c40 ut_handle installed by the following function:-]
00:00000:00010:2006/07/12 15:27:10.89 kernel [Handler pc: 0x5c0c40 ut_handle installed by the following function:-]
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x40dc1c conn_hdlr+ 0xb5c (0x20014b38, 0x20013830, 0x1c001c, 0x20014b38)
00:00000:00010:2006/07/12 15:27:10.89 kernel pc: 0x89c1c6 kpntwrapper+ 0x96 (0x89c130, 0x20014b38, 0x0, 0x0)
00:00000:00010:2006/07/12 15:27:10.96 kernel pc: 0x7c80b50b kernel32.dll (0x661b4e, 0x20821800, 0xff, 0x2)
00:00000:00010:2006/07/12 15:27:10.96 kernel end of stack trace, spid 10, kpid 1900573, suid 11
------------------------
Transact sql pour executer la proc
Code :
1
2
3
4
5
----------
DECLARE @i decimal
exec stpr_get_counter 'NAME',@i
SELECT @i
----------
Code de la proc
Code :
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 Procedure stpr_get_counter
@countername VARCHAR(128),
@countervalue DECIMAL = NULL OUTPUT
AS
 
 DECLARE @errmsg VARCHAR(255)
 DECLARE @strQuery VARCHAR(255)
 DECLARE @ok INT
  DECLARE @nextvalue DECIMAL
 
  SELECT @ok = 0
 SELECT @nextvalue = -1
 
 SET NOCOUNT ON
 
-- Highest transaction level. Only one connection can enter this at the same 
time
 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
 BEGIN TRAN GET_COUNTER
 
 SELECT @ok = COUNT(*) FROM ref_counters WHERE cnt_name = @countername
 IF @@ERROR > 0
 BEGIN
  SELECT @errmsg = 'Failed on query SELECT COUNT(*) FROM ref_counters'
  GOTO ERROR_HANDLER
 END
-- Insert countername entry if necessary
 IF @ok = 0
 BEGIN
  SELECT @strQuery = 'INSERT INTO ref_counters (cnt_name, cnt_lastvalue) 
VALUES (''' +  @countername + ''', 0)'
  EXEC @strQuery
  IF @@ERROR > 0
  BEGIN
   SELECT @errmsg = 'Failed on statement INSERT INTO ref_counters'
   GOTO ERROR_HANDLER
  END
 END
 
-- Getting next counter value
 SELECT @nextvalue = cnt_lastvalue + 1 FROM ref_counters WHERE cnt_name = 
@countername
 IF @@ERROR > 0
 BEGIN
  SELECT @errmsg = 'Failed on query SELECT cnt_lastvalue+1 FROM 
ref_counters'
  GOTO ERROR_HANDLER
 END
-- Update last value in counters table
 UPDATE ref_counters SET cnt_lastvalue = @nextvalue WHERE cnt_name = 
@countername
 IF @@ERROR > 0
 BEGIN
  SELECT @errmsg = 'Failed on statement UPDATE ref_counters'
  GOTO ERROR_HANDLER
 END
-- Return counter
 SELECT @countervalue = @nextvalue
 
 SELECT @countervalue
 
-- Commit transaction
 COMMIT TRAN GET_COUNTER
 
 SET NOCOUNT OFF
 RETURN 0
 
ERROR_HANDLER:
 ROLLBACK TRAN GET_COUNTER
 SET NOCOUNT OFF
 RAISERROR @@ERROR
 PRINT @errmsg
 RETURN @@ERROR
 
------------------------------------------
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2006, 16h33   #2
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
Bonjour,

Je viens de répondre sur les forums Sybase, mais je peux reposter ici...

Le problème vient à priori du "execute immediate" qui n'est disponible qu'à partir de la version 12. De plus la syntaxe correcte serait:

Code :
1
2
 
EXEC (@sqlCommand)
où les parenthèses sont obligatoire pour indiquer que @sqlCommand ne contient pas le nom d'une proc stockée ou d'une RPC.

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2006, 16h42   #3
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118


Si ça ne vous dérange pas on peut continuer ici?

Citation:
Envoyé par sur le forum sybase j'ai répondu
Merci de votre aide.

J'ai traduit le code d'une proc stock SQL SERVER 2000 et avant il y avait
les parenthèses.
J'ai enlever les parenthèses car la proc ne fonctionnait pas avec (erreur
script création)

Savez vous quelles sont les alternatives à EXEC pour la 11.9 ?

Merci

Abel
Edit : PS: Auriez vous quelques instants à consacrer à ceci ?
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2006, 17h31   #4
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118
J'ai trouvé ça et apparement ça marche
http://www.sypron.nl/dynsqlcis.html

Merci
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2006, 17h50   #5
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
C'était exactement ce que j'allais suggérer...

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2006, 18h21   #6
Rédacteur/Modérateur
 
Avatar de fadace
 
Homme Fabien Celaia
Administrateur de base de données
Inscription : octobre 2002
Messages : 3 779
Détails du profil
Informations personnelles :
Nom : Homme Fabien Celaia
Âge : 41
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Service public

Informations forums :
Inscription : octobre 2002
Messages : 3 779
Points : 8 124
Points : 8 124
Envoyer un message via ICQ à fadace Envoyer un message via Skype™ à fadace
Citation:
Envoyé par abelman
J'ai trouvé ça et apparement ça marche
http://www.sypron.nl/dynsqlcis.html

Merci
Oui, c'est un grand classique que de boucler sur son propre serveur via CIS... par contre attention aux perfs...
__________________
Sr DBA Oracle / Sybase / MS-SQL / DB2 / Informix / Postgresql
Administrateur SAP
Mes articles

Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums !
fadace est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2006, 19h59   #7
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118
Re, j'ai mis résolu trop vite.

J'ai suivi à la lettre les indications du site sypron

J'ai configuré mon serveur pour CIS avec les deux scripts et cela a fonctionné.

Par contre quand j'éxecute ma proc, il me dit qu'il ne trouve pas la table ref_counters. (REquête INSERT INTO ref_counters .. dans ma proc plus haut)

Qui existe bel et bien.

J'ai fait quelques test et j'ai vu que ça marche quand je prefixe la table par le nom de la base de données.

J'arrive à le faire pour le insert.

Comme ça
Code :
1
2
3
4
5
	SELECT @db=db_name() 
    	PRINT @db 
        SELECT @strQuery = 'INSERT INTO ' + @db + '..ref_counters (cnt_name, cnt_lastvalue) VALUES (''' +  @countername + ''', 0)'  
        PRINT @strQuery 
        EXEC sp_exec_dynsql @strQuery
Mais comment faire pour ce genre de requête pour prefixer???

Code :
1
2
3
4
5
6
7
8
9
--  Getting next counter value  
    SELECT @nextvalue = cnt_lastvalue + 1 FROM ref_counters WHERE cnt_name = @countername  
    IF @@ERROR > 0  
    BEGIN  
        SELECT @errmsg = 'Failed on query SELECT cnt_lastvalue+1 FROM ref_counters'  
        GOTO ERROR_HANDLER  
    END  
--  Update last value in counters table  
    UPDATE ref_counters SET cnt_lastvalue = @nextvalue WHERE cnt_name = @countername
Il faut utiliser les curseurs? Je ne sais pas les utiliser (pr l'instant). Vous connaissez des tutos dessus? ou bien avez vous d'autres suggestions?

Merci
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2006, 22h27   #8
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118


Merci de ne pas tenir compte de mon dernier message.
Je vais prefixer le nom de la base en dur directement dans les requêtes car la proc est un objet d'une seule base ...

@+
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/07/2006, 10h46   #9
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118
Re bonjour,

Alors j'ai essayer d'utiliser ma nouvelle proc stock avec la gestion du Exec contourné avec les Remote IO. (Sybase 11.9.2)

ça ne marche pas.

Le code suivant bloque et je n'ai plus la main. (Je dois tuer l'application pour reprendre la main)

Code :
1
2
3
declare @cpt decimal
exec @cpt=stpr_get_counter 'compteurx'
SELECT @cpt
Quand je regarde l'état du processus dans Sybase central, j'ai:
ID=1
Programme = SQL_Advantage
Commande= EXECUTE
Login=sa
Etat = remote i/o

Je n'ai rien dans les logs.

Une idée? Devrais je avoir un service annexe Sybase qui tourne? Qu'est ce que c'est qu'un XP server par exemple? Dans mes logs j'ai toujours un 'XP Server is not running' lors de l'arrêt du serveur.

JE remet le code de la proc stock ici
Code :
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
------------------------------------------------
 CREATE Procedure stpr_get_counter  
@countername VARCHAR(128),  
@countervalue DECIMAL = NULL OUTPUT  
AS  
 
    DECLARE @errmsg VARCHAR(255)  
    DECLARE @strQuery VARCHAR(255)  
    DECLARE @ok INT  
    DECLARE @nextvalue DECIMAL  
    DECLARE @dbname VARCHAR(50) 
 
    SELECT @ok = 0  
    SELECT @nextvalue = -1  
 
    SET NOCOUNT ON  
 
--  Highest transaction level. Only one connection can enter this at the same time  
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE  
    BEGIN TRAN GET_COUNTER  
 
--  Search for coutername entry in counter table  
    --SET @ok = 0  
    SELECT @ok = COUNT(*) FROM ref_counters WHERE cnt_name = @countername  
    IF @@ERROR > 0  
    BEGIN  
        SELECT @errmsg = 'Failed on query SELECT COUNT(*) FROM ref_counters'  
        GOTO ERROR_HANDLER  
    END  
-- Insert countername entry if necessary  
    IF @ok = 0  
    BEGIN  
    		SELECT @dbname=db_name() 
    		PRINT @dbname 
        SELECT @strQuery = 'INSERT INTO ' + @dbname + '..ref_counters (cnt_name, cnt_lastvalue) VALUES (''' +  @countername + ''', 0)'  
        PRINT @strQuery 
        EXEC sp_exec_dynsql @strQuery  
        IF @@ERROR > 0  
        BEGIN  
            SELECT @errmsg = 'Failed on statement INSERT INTO ref_counters'  
            GOTO ERROR_HANDLER  
        END  
    END  
 
--  Getting next counter value  
    SELECT @nextvalue = cnt_lastvalue + 1 FROM ref_counters WHERE cnt_name = @countername  
    IF @@ERROR > 0  
    BEGIN  
        SELECT @errmsg = 'Failed on query SELECT cnt_lastvalue+1 FROM ref_counters'  
        GOTO ERROR_HANDLER  
    END  
--  Update last value in counters table  
    UPDATE ref_counters SET cnt_lastvalue = @nextvalue WHERE cnt_name = @countername  
    IF @@ERROR > 0  
    BEGIN  
        SELECT @errmsg = 'Failed on statement UPDATE ref_counters'  
        GOTO ERROR_HANDLER  
    END  
--  Return counter  
    SELECT @countervalue = @nextvalue  
 
    SELECT @countervalue  
 
--  Commit transaction  
    COMMIT TRAN GET_COUNTER  
 
    SET NOCOUNT OFF  
    RETURN @countervalue
 
ERROR_HANDLER:  
    ROLLBACK TRAN GET_COUNTER  
    SET NOCOUNT OFF  
    PRINT @errmsg 
    --RAISERROR @@ERROR   
    RETURN @@ERROR
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/07/2006, 11h30   #10
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
Le XP server permet d'exécuter une command OS ou du code C ad-hoc comme une proc stockée. Ce module n'est donc pas en cause ici.

Je suspecte qu'il y a peut-être un problème de logique au niveau des transactions avec l'appel imbriqué de l'insert via sp_remote_sql. Il faut savoir que cet appel ne peut pas être fait dans le contexte de la transaction en cours, et si la requete qui est exécutée par sp_remote_sql doit accèder à une table qui est bloquée par la transaction démarrée dans la proc stpr_get_counter alors elle risque de tout bloquer.

Pour vérifier il suffit d'ouvirir une connexion supplémentaire et de faire un sp_who. Si le process est bloqué en "lock sleep" alors cela confirmerait cette analyse.

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/07/2006, 15h03   #11
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118
Effectivement c'est le cas.

Quand j'enlève le niveau d'isolation maximum
Code :
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
ça fonctionne très bien.

Le problème c'est que cette procedure sera très probablement sollicitée par plusieurs processus différents et de manière simultanée souhaitant obtenir la même valeur de compteur.

Comment faire dans ce cas pour garantir l'intégrité du compteur retourné? (pas de doublons)

Merci de votre aide en tout cas.
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/07/2006, 15h51   #12
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
On pourrait imaginer créer une table annexe pour controler l'accès. Cette table n'aurait qu'un enregistrement qui serait mis à jour (sans commit) en entrant dans la proc. Cela devrait permettre de serialiser l'accès.

Par example:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
CREATE TABLE the_semaphore(spid int)
go
INSERT the_semaphore VALUES(0)
go
 
CREATE proc get_counter ...
begin
 
begin tran
 
UPDATE the_semaphore SET spid = @@spid
 
... le reste de la proc ...
 
commit tran
En principe cela devrait permettre l'exécution unitaire de la proc get_counter.

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/07/2006, 16h09   #13
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118
mmh ..
Je suis désolé mais là je crois que mes limites sur le Transact SQL sont atteintes.

La simple présence d'un update suffira à sérialiser l'accès? Car j'ai déjà un update dans le code de la proc.

Ou bien il faut en plus que je vérifie à la fin de la proc que le spid présent dans la table semaphore est bien celui de la connection en cours, et si ce n'est pas le cas recommencer le traitement (ce qui implique une boucle et ne me plait pas trop car ça peut partir théoriquement à l'infini)

Un truc comme ça ?

Par ailleurs au lieu de creer une table je rajouterai plutot une colonne spid à la table ref_counters

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE proc get_counter ...
begin
 
begin tran
 
start:
UPDATE the_semaphore SET spid = @@spid
 
... le reste de la proc ...
 
declare @sem int
SELECT @sem = spid FROM the_semaphore
IF @sem <> @@spid then
goto start -- gerer un nombre max d'itérations avant de renvoyer erreur
 
commit tran
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/07/2006, 08h15   #14
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
L'idée est de créer un verrou au début de l'accès à la proc. Avec une table avec un seul row le verrou posé par un UPDATE sera un EX_TABLE (exclusif sur la table). Comme l'accès suivant veut faire le même verrou il devra attendre que le précedant execute le COMMIT (ce qui libère le verrou).

L'idée est évidemment d'éviter un verrou sur la table ref_counters, puisque cette table doit être accèdée par l'appel à sp_remote_sql, ce qui se fait via une autre connexion, et donc dans un contexte transactionel différent. Si notre proc pose un verrou sur ref_counters alors l'appel à sp_remote_sql pour faire une mise à jour de ref_counters va bloquer (comme on a vu avec l'utilisation du SET TRANSACTION LEVEL...)

Donc on crée un verrou dans une autre table (la donnée qu'on met dans cette autre table importe peu) pour arriver au comportement souhaité.

C'est évidemment assez tordu, mais comme on essaie de faire de l'EXECUTE IMMEDIATE quand cette fonctionalité n'existe pas vraiment il faut trouver des moyens détournés...

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/07/2006, 11h53   #15
Rédacteur
 
Avatar de abelman
 
Inscription : février 2003
Messages : 1 109
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 1 109
Points : 1 118
Points : 1 118
Merci beaucoup c'est clair et cohérent..
Et cela semble fonctionner ... pour l'instant ;-)

Encore merci
__________________
Les règles, Mode d'emploi
FAQS, Rechercher
.NET, C++
abelman est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 10h54.


 
 
 
 
Partenaires

Hébergement Web