Table SQL bloquée et transaction cancelée

Signaler
Messages postés
52
Date d'inscription
lundi 5 janvier 2004
Statut
Membre
Dernière intervention
19 novembre 2013
-
Messages postés
52
Date d'inscription
lundi 5 janvier 2004
Statut
Membre
Dernière intervention
19 novembre 2013
-
Bonjour

J'ai un petit programme qui fait de la mise à jour dans une table SQL Server. Or, de temps en temps, j'obtiens le message d'erreur suivant :
La transaction (processus ID = #xx) a été bloquée par un autre processus et a été choisie comme victime. Relancer la transaction

D'autre fois, lors de l'exécution de la méthode Update, j'ai le message délai expiré.

Pas glop : que faire ????
A voir également:

12 réponses

Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
salut

deja tu peux regarder dans tes logs de SQL serveur ce qui a bloqué la transaction.

cette erreur est due au fait que tu fait un requete sur une table qui est lockée par un autre processus.

dans ce cas, la deuxieme requete attend que la premiere ai fini. mais si la premiere est trop longue, la deuxieme tombe en timeout;

de meme, si deux processus se bloquent mutuellement, SQL serveur va en choisir un comme "victime", et sa transaction est alors annulée. c'est ce qui se passe dans ton cas.

ca te fait ca a chque fois ?
tu as d'autre choses qui font des requetes sur ton serveur ?
Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
j'ai pas précisé, ca peut aussi venir d'une ancienne transaction qui n'a pas été correctement terminée (pas de rollback ni de commit) tu peux verifier ca aussi dans tous les client qui accedent a ta base.
Messages postés
361
Date d'inscription
mercredi 21 mai 2003
Statut
Membre
Dernière intervention
12 novembre 2009
2
Salut,

C'est parcequ tu as des exclusives locks. Ces locks sont provoqués lorsque tu fait une mise à jour d'un record et que veux modifier ce ou ces mêmes enregistrement alors que l'autre modification n'a pas été terminée. Il chosit une des 2 transcations et la tue pour ne pas qu'il y ait de problème. Ce genre de problème arrive parfois lorsque tu utilise des sub queries dans l'update.

A+
Messages postés
52
Date d'inscription
lundi 5 janvier 2004
Statut
Membre
Dernière intervention
19 novembre 2013

Réponse à aieeeuuuuuuuuuuuuuuu : la base est alimentée par un applicatif intranet (ASP) qui crée plusieurs records dans plusieurs tables, à l'intérieur d'une transaction. A ma connaissance, il y a toujours le couple begintrans - committrans.

Un applicatif VB6 accède à cette base pour faire des mises à jour sur une table particulière. Il n'utilise pas la notion de transaction, et c'est lui qui se plante, mais pas systématiquement.

Réponse à gaa179 : le loctype du recordset est optimistic, le curseur est le curseur par défaut, mais je ne sais pas à quoi correspondent ces 2 notions

Question : y a-t-il un moyen d'empécher le programme de se planter ???

Merci de vos réponse
Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
par hasard, est ce que tes applications asp n'ouvrirait pas des transactions qu'elles refermeraient dans une autre page ?
dance ce cas il se peut qu'une transaction soit ouverte pendant une longue duree, voir reste ouverte si l'explorateur est fermé.

sinon tu ne m'a pas repondu : est ce que ca te fait ca a chaque fois ?


tu as essayé killer tous les processus de ta base (ou de la redemarrer) et voir si le probleme persiste.


pour isoler le probleme, tu peux essayer de faire le test sur une autre base sur laquelle seulton programme accede. tu pourra comme ca voir d'ou vient le probleme : de ton programme ou d'une autre application qui entre en conflit avec ton programme
Messages postés
52
Date d'inscription
lundi 5 janvier 2004
Statut
Membre
Dernière intervention
19 novembre 2013

L'appli ASP traite toute la transaction dans la même page, donc à priori, pas de pb de ce coté là.

D'autre part, le programme VB ne se plante que de temps en temps, et on peut le lancer plusieurs fois de suite sans plantage.
Si je le lance seul sur une autre base, aucun pb ???
Messages postés
361
Date d'inscription
mercredi 21 mai 2003
Statut
Membre
Dernière intervention
12 novembre 2009
2
Salut,

Dans le SQL Enterprise Manager, tu peux regarder qui fait les exclusives locks.
Si tu pouvais donner ton asp qui traite de la transaction, cela pourrait aider.

A+
Messages postés
52
Date d'inscription
lundi 5 janvier 2004
Statut
Membre
Dernière intervention
19 novembre 2013

Voici le code ASP :

set cn=server.CreateObject("ADODB.Connection")
cn.Open Application("xxx_ConnectionString")
cn.BeginTrans

set rs=server.CreateObject("ADODB.Recordset")
rs.LockType = adLockOptimistic

sQuery "SELECT * FROM table1 WHERE cle1 0"
rs.Open sQuery,cn
rs.AddNew
rs.Fields("cle1") = nnn
rs.Fields("champ1") = "xxx"
...
rs.Update
rs.Close

sQuery "SELECT * FROM table2 WHERE cle2 0"
rs.Open sQuery,cn
rs.AddNew
rs.Fields("cle2") = nnn
rs.Fields("champ2") = "yyyy"
...
rs.Update
rs.Close

cn.CommitTrans
cn.Close

Set rs = Nothing
set cn = nothing
Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
as tu autre chose qui tourne sur cette base hormis l'asp et ton programme ?

sinon essaie dans ton code ASP de faire une SELECT * FROM maTable WITH(NOLOCK), monAutreTable WITH(NOLOCK) ...

ca evite de bloquer les tables dasn lesquelles tu fais des requetes.

essaie ca et dis nous ce que ca donne.


de meme pour ton update


une autre question : combien de temps durent tes requetes les plus longues ?


est-ce qu'il s'agit de grosses tables ?
Messages postés
52
Date d'inscription
lundi 5 janvier 2004
Statut
Membre
Dernière intervention
19 novembre 2013

Je viens de découvrir un 3ème programme qui accède à la base, et je pense que c'est lui qui bloque car sa structure est la suivante :

sQuery = "SELECT * FROM table1 WHERE ..."
rs.Open sQuery,cn
do until rs.eof
.....
ici un traitement très long qui peut durer plusieurs minutes, et qui ne fait pas d'accès à la base
....
ici la procédure de mise à jour de la base
rs.Fields("champ1") = "xxx"
rs.Update

loop
rs.Close

Je pense donc que c'est cette boucle qui bloque la base
Qu'en pensez-vous ?
Messages postés
698
Date d'inscription
jeudi 16 janvier 2003
Statut
Membre
Dernière intervention
20 mai 2011
2
ha oui, ca pourrait bien venir de la !
surtout si tu fait un update.

en gros, quand tu ouvre ton recordset (rs.open), les tables qui sont appeles par la requetes deviennent innaccesibles par d'autre sprocessus jusqu'a ce que tu termine ta transaction. si tu fait une boucle avec un traitement long, ca peut donc bloquer tes tables pendant pas mal de temps.

ce qu'il faut donc que tu fasse, c'est valider ta transaction après chaque update par exemple.
regarde tu coté de la propriété isolationLevel de ta connexion si c'est une ADODB.


ce programme n'ouvre nul part de transcation de façon explicite ?


je ne connais pas trop toutes les methodes au niveau ADODB, essaie peut etre juste en mettant le rs.update juste avant de fermer ta connexion. reagarde un peu sur le site si tu trouve des choses a ce sujet, pour ne pas bloquer tes tables...

sinon tu peux regarder ca aussi :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_ca-co_2f3o.asp

c'est les MSDN SQL Server sur UPDATE. jette un oeil sur la partie <table_hint_limited> pour voir si il n'y a pas un type de verrou qui pourrait resoudre ton probleme.

car apres ca va dependre de comment tu accede a quelles tables avec tes requetes...
Messages postés
52
Date d'inscription
lundi 5 janvier 2004
Statut
Membre
Dernière intervention
19 novembre 2013

OK et merci pour votre aide !