|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Bonjour,
Ma question est peut-être surprenante, je sais que Sql server gère les blocages lors des mémorisations tout seul mais je vous expose le souci : Dans le cadre d'utilisation multi-postes, une même fiche peut-être appelée par plusieurs postes. Je souhaite afficher un message ou interdire la modification d'une information si celle-ci est déjà affichée et en cours de modification sur un autre poste. Par exemple, la fiche du client "Toto" est en cours de modification sur un poste X. Le poste Y veut lui aussi modifier cette fiche. Je désire bloquer la fiche sur le poste X et lors de son appel sur le poste Y afficher "le client est en cours de modification sur un autre poste". Quelles instructions Sql permettent de bloquer, vérifier le blocage et débloquer une ligne ? Mon but n'est pas d'avertir le 2ème utilisateur, après qu'il ait saisi ses modifications, que la fiche a déjà été modifiée par quelqu'un d'autres pendant ce temps. Ca je pourrais le faire en testant des colonnes dans lesquelles je mémoriserais les dates et heures des dernières modifications. Je pourrais aussi rajouter une colonne dans les tables concernées pour un mettre le code de l'utilisateur concerné et l'enlever à la fin de sa modification, mais en cas de plantage, la valeur reste dans la colonne et la ligne est toujours considérée comme bloquée. Voila, je ne sais pas si j'ai été très clair dans ma demande ... Merci de vos conseils Jean |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Juanito a écrit: > Dans le cadre d'utilisation multi-postes, une même fiche peut-être > appelée par plusieurs postes. Je souhaite afficher un message ou > interdire la modification d'une information si celle-ci est déjà > affichée et en cours de modification sur un autre poste. Bonjour, Le meilleur moyen de le faire, est de gérer ce blocage manuellement, dans une table de verrous, qui contient le nom de la table, la clé primaire de la ligne, avec date de verrou, spid et utilisateur. Ci-dessous le code de deux procédures idoines que j'avais faites pour ça il y a qq années (SQL Server 2000, préfixées par sp_ et posées dans Master). CREATE PROCEDURE dbo.sp_lockRecord @recordType varchar(30), @recordId int, @done smallint output, @msg varchar(150) output, @DbId smallint = NULL AS BEGIN SET NOCOUNT ON IF @DbId IS NULL SET @DbId = DB_ID() IF EXISTS (SELECT 1 FROM tools.dbo.RecordLock WHERE RecordType = @recordType AND RecordId = @recordId AND DatabaseId = @DbId) BEGIN SELECT @msg = 'Record locked in database ' + DB_NAME(@DbId) + ' by ' + ISNULL(u.FullName, 'unknown') + ' since ' + CONVERT(varchar(30), l.LockingTime, 109) + ' from ' + RTRIM(l.HostName) FROM tools.dbo.RecordLock l LEFT JOIN contacts.dbo.v_perm_UserFullInfo u ON u.DatabaseLogin = l.DatabaseLogin WHERE l.RecordType = @recordType AND l.RecordId = @recordId AND l.DatabaseId = @DbId SET @done=0 END ELSE BEGIN INSERT INTO tools.dbo.RecordLock WITH (ROWLOCK) (DatabaseLogin,Hostname, DatabaseId, RecordType, RecordId, LockingTime) VALUES(tools.dbo.fn_sysuser(), ISNULL(HOST_NAME(),'unknown'), @DbId, @recordType, @recordId, GETDATE()) SET @msg='Locked ok' SET @done=1 END END CREATE PROCEDURE dbo.sp_unlockRecord @recordType varchar(30), @recordId int, @done smallint output, @msg varchar(80) output, @DbId smallint = NULL AS BEGIN SET NOCOUNT ON DECLARE @rowcount int IF @DbId IS NULL SET @DbId = DB_ID() DELETE tools.dbo.RecordLock WITH (ROWLOCK) WHERE DatabaseId = @DbId AND RecordType = @recordType AND RecordId = @recordId SELECT @done = @@ERROR, @rowcount = @@ROWCOUNT IF (@RowCount = 0) BEGIN SET @done = 1 SET @msg = 'Record not locked!' END ELSE IF @done = 0 BEGIN SET @done = 1 SET @msg = 'Unlocked ok!' END ELSE BEGIN SET @done=0 SET @msg = 'Error while unlocking!' END END -- Rudi Bruchez Consultant independant, MCDBA, MCITP, MCT http://www.babaluga.com/ http://rudi.developpez.com/ |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
En complément le verrouillage optimisite est en fait souvent géré par l'API
permettant l'accès aux données (ADO, ADO.NET) : - soit en testant que les valeurs originales n'ont pas été changées (fait par l'API) - soit en testant la colonne de type "rowversion" présente dans la table (cette colonne est automatiquement mise à jour à chaque update donc permet de tester cela facilement). (fait par l'API) - et ce principe ne pose donc pas de souci en cas de blocage de l'application - ne reste donc finalement plus au développeur qu'à gérer quoi faire en cas de conflit Le message original laisse supposer que la verrouillage optimiste pourrait ne pas avoir été choisi car considéré comme plus compliqué, moins robuste et devant être géré explicitement. Si c'est le cas, la question serait peut-être à reconsidérer car c'est plutôt le contraire... -- Patrice "Rudi Bruchez" <rudi#nospam#at#babaluga.com> a écrit dans le message de news: %23u4lHdcNIHA.3400@TK2MSFTNGP03.phx.gbl... > > > Juanito a écrit: > >> Dans le cadre d'utilisation multi-postes, une même fiche peut-être >> appelée par plusieurs postes. Je souhaite afficher un message ou >> interdire la modification d'une information si celle-ci est déjà >> affichée et en cours de modification sur un autre poste. > > Bonjour, > > Le meilleur moyen de le faire, est de gérer ce blocage manuellement, > dans une table de verrous, qui contient le nom de la table, la clé > primaire de la ligne, avec date de verrou, spid et utilisateur. > > Ci-dessous le code de deux procédures idoines que j'avais faites pour ça > il y a qq années (SQL Server 2000, préfixées par sp_ et posées dans > Master). > > CREATE PROCEDURE dbo.sp_lockRecord > @recordType varchar(30), > @recordId int, > @done smallint output, > @msg varchar(150) output, > @DbId smallint = NULL > AS BEGIN > SET NOCOUNT ON > > IF @DbId IS NULL SET @DbId = DB_ID() > > IF EXISTS (SELECT 1 FROM tools.dbo.RecordLock WHERE RecordType = > @recordType AND RecordId = @recordId AND DatabaseId = @DbId) BEGIN > SELECT > @msg = 'Record locked in database ' + DB_NAME(@DbId) + ' by ' + > ISNULL(u.FullName, 'unknown') + ' since ' + > CONVERT(varchar(30), l.LockingTime, 109) + ' from ' + RTRIM(l.HostName) > FROM > tools.dbo.RecordLock l > LEFT JOIN contacts.dbo.v_perm_UserFullInfo u ON u.DatabaseLogin = > l.DatabaseLogin > WHERE > l.RecordType = @recordType AND > l.RecordId = @recordId AND > l.DatabaseId = @DbId > > SET @done=0 > END ELSE BEGIN > INSERT INTO tools.dbo.RecordLock WITH (ROWLOCK) > (DatabaseLogin,Hostname, DatabaseId, RecordType, RecordId, LockingTime) > VALUES(tools.dbo.fn_sysuser(), ISNULL(HOST_NAME(),'unknown'), @DbId, > @recordType, @recordId, GETDATE()) > > SET @msg='Locked ok' > SET @done=1 > END > > END > > CREATE PROCEDURE dbo.sp_unlockRecord > @recordType varchar(30), > @recordId int, > @done smallint output, > @msg varchar(80) output, > @DbId smallint = NULL > AS BEGIN > SET NOCOUNT ON > DECLARE @rowcount int > > IF @DbId IS NULL SET @DbId = DB_ID() > > DELETE tools.dbo.RecordLock WITH (ROWLOCK) > WHERE DatabaseId = @DbId AND > RecordType = @recordType AND > RecordId = @recordId > SELECT @done = @@ERROR, > @rowcount = @@ROWCOUNT > > IF (@RowCount = 0) BEGIN > SET @done = 1 > SET @msg = 'Record not locked!' > END ELSE IF @done = 0 BEGIN > SET @done = 1 > SET @msg = 'Unlocked ok!' > END ELSE BEGIN > SET @done=0 > SET @msg = 'Error while unlocking!' > END > END > > > -- > Rudi Bruchez > Consultant independant, MCDBA, MCITP, MCT > http://www.babaluga.com/ > http://rudi.developpez.com/ |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
BEGIN TRANSACTION SELECT .... FROM ... (UPDLOCK) .... END TRANSACTION -- Thierry "Juanito" <jean.cougnaud@libertysurf.fr> a écrit dans le message de news: mn.1b817d7c7debc995.68503@libertysurf.fr... > Bonjour, > > Ma question est peut-être surprenante, je sais que Sql server gère les > blocages lors des mémorisations tout seul mais je vous expose le souci : > > Dans le cadre d'utilisation multi-postes, une même fiche peut-être appelée > par plusieurs postes. Je souhaite afficher un message ou interdire la > modification d'une information si celle-ci est déjà affichée et en cours > de modification sur un autre poste. > > Par exemple, la fiche du client "Toto" est en cours de modification sur un > poste X. Le poste Y veut lui aussi modifier cette fiche. Je désire bloquer > la fiche sur le poste X et lors de son appel sur le poste Y afficher "le > client est en cours de modification sur un autre poste". > > Quelles instructions Sql permettent de bloquer, vérifier le blocage et > débloquer une ligne ? > > Mon but n'est pas d'avertir le 2ème utilisateur, après qu'il ait saisi ses > modifications, que la fiche a déjà été modifiée par quelqu'un d'autres > pendant ce temps. Ca je pourrais le faire en testant des colonnes dans > lesquelles je mémoriserais les dates et heures des dernières > modifications. > > Je pourrais aussi rajouter une colonne dans les tables concernées pour un > mettre le code de l'utilisateur concerné et l'enlever à la fin de sa > modification, mais en cas de plantage, la valeur reste dans la colonne et > la ligne est toujours considérée comme bloquée. > > Voila, je ne sais pas si j'ai été très clair dans ma demande ... > > Merci de vos conseils > > Jean > > |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Erratum :
COMMIT TRANSACTION au lieu de END TRANSACTION -- Thierry "Thierry" <tper_NOSPAM@vfemail.net> a écrit dans le message de news: uinJhvcNIHA.1204@TK2MSFTNGP03.phx.gbl... > > BEGIN TRANSACTION > SELECT .... FROM ... (UPDLOCK) > > ... > > END TRANSACTION > > -- > Thierry > > > "Juanito" <jean.cougnaud@libertysurf.fr> a écrit dans le message de news: > mn.1b817d7c7debc995.68503@libertysurf.fr... >> Bonjour, >> >> Ma question est peut-être surprenante, je sais que Sql server gère les >> blocages lors des mémorisations tout seul mais je vous expose le souci : >> >> Dans le cadre d'utilisation multi-postes, une même fiche peut-être >> appelée par plusieurs postes. Je souhaite afficher un message ou >> interdire la modification d'une information si celle-ci est déjà affichée >> et en cours de modification sur un autre poste. >> >> Par exemple, la fiche du client "Toto" est en cours de modification sur >> un poste X. Le poste Y veut lui aussi modifier cette fiche. Je désire >> bloquer la fiche sur le poste X et lors de son appel sur le poste Y >> afficher "le client est en cours de modification sur un autre poste". >> >> Quelles instructions Sql permettent de bloquer, vérifier le blocage et >> débloquer une ligne ? >> >> Mon but n'est pas d'avertir le 2ème utilisateur, après qu'il ait saisi >> ses modifications, que la fiche a déjà été modifiée par quelqu'un >> d'autres pendant ce temps. Ca je pourrais le faire en testant des >> colonnes dans lesquelles je mémoriserais les dates et heures des >> dernières modifications. >> >> Je pourrais aussi rajouter une colonne dans les tables concernées pour un >> mettre le code de l'utilisateur concerné et l'enlever à la fin de sa >> modification, mais en cas de plantage, la valeur reste dans la colonne et >> la ligne est toujours considérée comme bloquée. >> >> Voila, je ne sais pas si j'ai été très clair dans ma demande ... >> >> Merci de vos conseils >> >> Jean >> >> > > |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Bonsoir,
Merci pour l'explication et le code je vais l'étudier. Cordialement Jean Rudi Bruchez a émis l'idée suivante : > > Juanito a écrit: > >> Dans le cadre d'utilisation multi-postes, une même fiche peut-être >> appelée par plusieurs postes. Je souhaite afficher un message ou >> interdire la modification d'une information si celle-ci est déjà >> affichée et en cours de modification sur un autre poste. > > Bonjour, > > Le meilleur moyen de le faire, est de gérer ce blocage manuellement, > dans une table de verrous, qui contient le nom de la table, la clé > primaire de la ligne, avec date de verrou, spid et utilisateur. > > Ci-dessous le code de deux procédures idoines que j'avais faites pour ça > il y a qq années (SQL Server 2000, préfixées par sp_ et posées dans Master). > > CREATE PROCEDURE dbo.sp_lockRecord > @recordType varchar(30), > @recordId int, > @done smallint output, > @msg varchar(150) output, > @DbId smallint = NULL > AS BEGIN > SET NOCOUNT ON > > IF @DbId IS NULL SET @DbId = DB_ID() > > IF EXISTS (SELECT 1 FROM tools.dbo.RecordLock WHERE RecordType = > @recordType AND RecordId = @recordId AND DatabaseId = @DbId) BEGIN > SELECT > @msg = 'Record locked in database ' + DB_NAME(@DbId) + ' by ' + > ISNULL(u.FullName, 'unknown') + ' since ' + > CONVERT(varchar(30), l.LockingTime, 109) + ' from ' + RTRIM(l.HostName) > FROM > tools.dbo.RecordLock l > LEFT JOIN contacts.dbo.v_perm_UserFullInfo u ON u.DatabaseLogin = > l.DatabaseLogin > WHERE > l.RecordType = @recordType AND > l.RecordId = @recordId AND > l.DatabaseId = @DbId > > SET @done=0 > END ELSE BEGIN > INSERT INTO tools.dbo.RecordLock WITH (ROWLOCK) > (DatabaseLogin,Hostname, DatabaseId, RecordType, RecordId, LockingTime) > VALUES(tools.dbo.fn_sysuser(), ISNULL(HOST_NAME(),'unknown'), @DbId, > @recordType, @recordId, GETDATE()) > > SET @msg='Locked ok' > SET @done=1 > END > > END > > CREATE PROCEDURE dbo.sp_unlockRecord > @recordType varchar(30), > @recordId int, > @done smallint output, > @msg varchar(80) output, > @DbId smallint = NULL > AS BEGIN > SET NOCOUNT ON > DECLARE @rowcount int > > IF @DbId IS NULL SET @DbId = DB_ID() > > DELETE tools.dbo.RecordLock WITH (ROWLOCK) > WHERE DatabaseId = @DbId AND > RecordType = @recordType AND > RecordId = @recordId > SELECT @done = @@ERROR, > @rowcount = @@ROWCOUNT > > IF (@RowCount = 0) BEGIN > SET @done = 1 > SET @msg = 'Record not locked!' > END ELSE IF @done = 0 BEGIN > SET @done = 1 > SET @msg = 'Unlocked ok!' > END ELSE BEGIN > SET @done=0 > SET @msg = 'Error while unlocking!' > END > END |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Bonsoir,
Merci pour vos réponses, je vais regarder tout ça. Cordialement Jean Thierry a émis l'idée suivante : > Erratum : > > COMMIT TRANSACTION au lieu de END TRANSACTION > > > > -- > Thierry > > > "Thierry" <tper_NOSPAM@vfemail.net> a écrit dans le message de news: > uinJhvcNIHA.1204@TK2MSFTNGP03.phx.gbl... >> >> BEGIN TRANSACTION >> SELECT .... FROM ... (UPDLOCK) >> >> ... >> >> END TRANSACTION >> >> -- Thierry >> >> >> "Juanito" <jean.cougnaud@libertysurf.fr> a écrit dans le message de news: >> mn.1b817d7c7debc995.68503@libertysurf.fr... >>> Bonjour, >>> >>> Ma question est peut-être surprenante, je sais que Sql server gère les >>> blocages lors des mémorisations tout seul mais je vous expose le souci : >>> >>> Dans le cadre d'utilisation multi-postes, une même fiche peut-être appelée >>> par plusieurs postes. Je souhaite afficher un message ou interdire la >>> modification d'une information si celle-ci est déjà affichée et en cours >>> de modification sur un autre poste. >>> >>> Par exemple, la fiche du client "Toto" est en cours de modification sur un >>> poste X. Le poste Y veut lui aussi modifier cette fiche. Je désire bloquer >>> la fiche sur le poste X et lors de son appel sur le poste Y afficher "le >>> client est en cours de modification sur un autre poste". >>> >>> Quelles instructions Sql permettent de bloquer, vérifier le blocage et >>> débloquer une ligne ? >>> >>> Mon but n'est pas d'avertir le 2ème utilisateur, après qu'il ait saisi ses >>> modifications, que la fiche a déjà été modifiée par quelqu'un d'autres >>> pendant ce temps. Ca je pourrais le faire en testant des colonnes dans >>> lesquelles je mémoriserais les dates et heures des dernières >>> modifications. >>> >>> Je pourrais aussi rajouter une colonne dans les tables concernées pour un >>> mettre le code de l'utilisateur concerné et l'enlever à la fin de sa >>> modification, mais en cas de plantage, la valeur reste dans la colonne et >>> la ligne est toujours considérée comme bloquée. >>> >>> Voila, je ne sais pas si j'ai été très clair dans ma demande ... >>> >>> Merci de vos conseils >>> >>> Jean >>> >>> >> >> |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Bonjour,
J'ai regardé le code et en fait je cherche une solution qui n'irait pas mettre à jour une ligne dans une table de blocages. En fait, le développement que je fais est en Web et la crainte que j'ai est que s'il y a coupure de ligne ou un plantage qualconque, on se retrouve avec des lignes qui sont condidérées comme bloquées alors que cela n'est pas le cas. C'est pour cela que je cherchais une solution qui pourrait se débloquer seule. Pour expliquer un peu plus mon projet : j'ai des pages dans lesquelles je peux modifier des informations mais la sauvegarde ne se fait que lorsque l'on clique sur le bouton de validation. De plus, il faut imaginer une fiche "voiture". A cette voiture on peut affecter un moteur qui a un n° de série. J'ai donc un tableau avec les moteurs disponibles. Si on recherche les moteurs sur 2 postes différents, le moteur qui a été sélectionné sur un poste mais pas encore validé, apparaîtra comme disponible sur les autres postes alors qu'il ne l'est pas réellement car choisi sur un autre poste. Si je met une valeur "blocage" dans la table des moteurs et qu'il y a plantage, le moteur restera bloqué. C'est pour cela que je cherchais une solution pour que la base de données puisse "bloquer" une ligne et en cas de plantage puisse la libérer tout seul. Mais ça, je ne sais pas si cela existe. Jean Rudi Bruchez a utilisé son clavier pour écrire : > > Juanito a écrit: > >> Dans le cadre d'utilisation multi-postes, une même fiche peut-être >> appelée par plusieurs postes. Je souhaite afficher un message ou >> interdire la modification d'une information si celle-ci est déjà >> affichée et en cours de modification sur un autre poste. > > Bonjour, > > Le meilleur moyen de le faire, est de gérer ce blocage manuellement, > dans une table de verrous, qui contient le nom de la table, la clé > primaire de la ligne, avec date de verrou, spid et utilisateur. > > Ci-dessous le code de deux procédures idoines que j'avais faites pour ça > il y a qq années (SQL Server 2000, préfixées par sp_ et posées dans Master). > > CREATE PROCEDURE dbo.sp_lockRecord > @recordType varchar(30), > @recordId int, > @done smallint output, > @msg varchar(150) output, > @DbId smallint = NULL > AS BEGIN > SET NOCOUNT ON > > IF @DbId IS NULL SET @DbId = DB_ID() > > IF EXISTS (SELECT 1 FROM tools.dbo.RecordLock WHERE RecordType = > @recordType AND RecordId = @recordId AND DatabaseId = @DbId) BEGIN > SELECT > @msg = 'Record locked in database ' + DB_NAME(@DbId) + ' by ' + > ISNULL(u.FullName, 'unknown') + ' since ' + > CONVERT(varchar(30), l.LockingTime, 109) + ' from ' + RTRIM(l.HostName) > FROM > tools.dbo.RecordLock l > LEFT JOIN contacts.dbo.v_perm_UserFullInfo u ON u.DatabaseLogin = > l.DatabaseLogin > WHERE > l.RecordType = @recordType AND > l.RecordId = @recordId AND > l.DatabaseId = @DbId > > SET @done=0 > END ELSE BEGIN > INSERT INTO tools.dbo.RecordLock WITH (ROWLOCK) > (DatabaseLogin,Hostname, DatabaseId, RecordType, RecordId, LockingTime) > VALUES(tools.dbo.fn_sysuser(), ISNULL(HOST_NAME(),'unknown'), @DbId, > @recordType, @recordId, GETDATE()) > > SET @msg='Locked ok' > SET @done=1 > END > > END > > CREATE PROCEDURE dbo.sp_unlockRecord > @recordType varchar(30), > @recordId int, > @done smallint output, > @msg varchar(80) output, > @DbId smallint = NULL > AS BEGIN > SET NOCOUNT ON > DECLARE @rowcount int > > IF @DbId IS NULL SET @DbId = DB_ID() > > DELETE tools.dbo.RecordLock WITH (ROWLOCK) > WHERE DatabaseId = @DbId AND > RecordType = @recordType AND > RecordId = @recordId > SELECT @done = @@ERROR, > @rowcount = @@ROWCOUNT > > IF (@RowCount = 0) BEGIN > SET @done = 1 > SET @msg = 'Record not locked!' > END ELSE IF @done = 0 BEGIN > SET @done = 1 > SET @msg = 'Unlocked ok!' > END ELSE BEGIN > SET @done=0 > SET @msg = 'Error while unlocking!' > END > END |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Bonjour,
En fait j'aimerais que la ligne soit bloquée, que l'utilisateur puisse faire des saisies, des choix et à la fin mémoriser et débloquer. Donc il faut que je le fasse en plusieurs requêtes Sql qui seront espacées dans le temps. Est-ce possible ? J'ai essayé de faire une requête qui fait "Begin Transaction" Une autre qui fait "select MaColonne From MaTable (Updlock) Where MaCle='toto'" Je le lance sur 2 postes et cela ne me donne pas d'erreur... Je dois m'y prendre mal. En fait, j'ai travaillé avant avec des gestionnaires de fichiers indexés dans lesquels il y a des ordres de lecture bloquantes et des déblocages. On peut donc lire et bloquer un enregistrement, faire plein de traitements, de saisie ... et à la fin mémoriser et débloquer. Si un autre poste essaie de faire une lecture blocante sur le même enregistrement cela renvoie un mesasge d'erreur. J'aimerais reproduire la même chose. L'avantage du système est que si cela plante entre le blocage et le déblocage, le système débloque seul l'enregistrement. Merci d'avance Jean Le 03/12/2007, Thierry a supposé : > BEGIN TRANSACTION > SELECT .... FROM ... (UPDLOCK) > > ... > > END TRANSACTION > > -- > Thierry > > > "Juanito" <jean.cougnaud@libertysurf.fr> a écrit dans le message de news: > mn.1b817d7c7debc995.68503@libertysurf.fr... >> Bonjour, >> >> Ma question est peut-être surprenante, je sais que Sql server gère les >> blocages lors des mémorisations tout seul mais je vous expose le souci : >> >> Dans le cadre d'utilisation multi-postes, une même fiche peut-être appelée >> par plusieurs postes. Je souhaite afficher un message ou interdire la >> modification d'une information si celle-ci est déjà affichée et en cours de >> modification sur un autre poste. >> >> Par exemple, la fiche du client "Toto" est en cours de modification sur un >> poste X. Le poste Y veut lui aussi modifier cette fiche. Je désire bloquer >> la fiche sur le poste X et lors de son appel sur le poste Y afficher "le >> client est en cours de modification sur un autre poste". >> >> Quelles instructions Sql permettent de bloquer, vérifier le blocage et >> débloquer une ligne ? >> >> Mon but n'est pas d'avertir le 2ème utilisateur, après qu'il ait saisi ses >> modifications, que la fiche a déjà été modifiée par quelqu'un d'autres >> pendant ce temps. Ca je pourrais le faire en testant des colonnes dans >> lesquelles je mémoriserais les dates et heures des dernières modifications. >> >> Je pourrais aussi rajouter une colonne dans les tables concernées pour un >> mettre le code de l'utilisateur concerné et l'enlever à la fin de sa >> modification, mais en cas de plantage, la valeur reste dans la colonne et >> la ligne est toujours considérée comme bloquée. >> >> Voila, je ne sais pas si j'ai été très clair dans ma demande ... >> >> Merci de vos conseils >> >> Jean >> >> |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
> J'ai essayé de faire
> une requête qui fait "Begin Transaction" > Une autre qui fait "select MaColonne From MaTable (Updlock) Where > MaCle='toto'" >Je le lance sur 2 postes et cela ne me donne pas d'erreur... Normalement, sur le 2ème poste, la commande SQL doit sortir en erreur après un "Timeout" Est-tu certain de ne pas cloturer les connexions entre temps ? Verrouillage de la ligne 'toto' : BEGIN TRANSACTION select MaColonne From MaTable (Updlock) Where MaCle='toto' Déverrouillage : COMMIT TRANSACTION ROLLBACK ou bien fermeture de la connexion au serveur SQL. |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
Bonjour,
Juanito a écrit: > En fait, le développement que je fais est en Web et la crainte que j'ai > est que s'il y a coupure de ligne ou un plantage qualconque, on se > retrouve avec des lignes qui sont condidérées comme bloquées alors que > cela n'est pas le cas. Désolé, mais là c'est du domaine de la science-fiction. Ce que tu veux faire est utopique : dans un contexte web, il n'y a ni session, ni plantage. Une page web est délivrée sur le client, et ensuite tout lien avec le serveur est coupé. Si ton utilisateur clique sur le bouton validation deux semaines après avoir chargé la page, que veux-tu qu'il se passe ? Qu'est-ce qu'un plantage dans un contexte de client web ? -- Rudi Bruchez Consultant independant, MCDBA, MCITP, MCT http://www.babaluga.com/ http://rudi.developpez.com/ |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Rudi Bruchez a écrit :
> Bonjour, > > Juanito a écrit: > >> En fait, le développement que je fais est en Web et la crainte que j'ai >> est que s'il y a coupure de ligne ou un plantage qualconque, on se >> retrouve avec des lignes qui sont condidérées comme bloquées alors que >> cela n'est pas le cas. > > Désolé, mais là c'est du domaine de la science-fiction. Science fiction ou Fantastique ???? ;-) A + > Ce que tu veux > faire est utopique : dans un contexte web, il n'y a ni session, ni > plantage. Une page web est délivrée sur le client, et ensuite tout lien > avec le serveur est coupé. Si ton utilisateur clique sur le bouton > validation deux semaines après avoir chargé la page, que veux-tu qu'il > se passe ? > Qu'est-ce qu'un plantage dans un contexte de client web ? > -- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation *********************** http://www.sqlspot.com ************************* |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Juanito a écrit :
> Bonjour, > [...] > En fait, j'ai travaillé avant avec des gestionnaires de fichiers indexés > dans lesquels il y a des ordres de lecture bloquantes et des déblocages. > On peut donc lire et bloquer un enregistrement, faire plein de > traitements, de saisie ... et à la fin mémoriser et débloquer. Si un > autre poste essaie de faire une lecture blocante sur le même > enregistrement cela renvoie un mesasge d'erreur. J'aimerais reproduire > la même chose. D'ou vos question et votre erreur ! C'est le SGBDR qui fait tout cela de manière automatique... Commencez par apprendre comment fonctionne un SGBDR. A partir de là vous aurez compris que vos questions n'ont aucun sens... Mon site web comme mes bouquins peuvent vous y aider ! A + -- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation *********************** http://www.sqlspot.com ************************* |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
Bonjour,
Je comprends très bien que le Sgbdr gère les blocages durant les update. Cependant ce que je voudrais c'est réserver une ligne d'une table pour que les autres utilisateurs ne puissent pas l'utiliser. Même pendant plusieurs minutes. A ouvre un client B ouvre le même client A fait des modifs et les mémorise B fait d'autres modifications et les mémorise En fait, lorsque A rappelle le client il ne voit plus ses modifs mais celles effectuées par B. Soit le dernier qui mémorise gagne, soit on regarde par rapport à une colonne timestamp mise à jour lors des mémorisations et on indique que quelqu'un d'autre a fait des modifs entre temps et on refuse de mémoriser. Je préférerais indiquer un message à l'ouverture de la fiche du client que quelqu'un d'autre est en train de le modifier et qu'il ne peut pas le faire actuellement. Donc, si on ne peut pas bloquer une ligne je pourrais gérer ces semblants de blocages par une table dans laquelle je mettrais le nom de la table concernée, l'identifiant unique, l'utilisateur, la date et l'heure ... Pour "bloquer" une ligne j'ajoute dans cette table et pour "débloquer" je l'efface. Mais d'où ma remarque en cas de plantage ou de coupure de réseau. Cette table contiendra des lignes considérées comme bloquées alors que cela n'est pas le cas. J'ai effectivement regardé votre site et parcouru un de vos livres. Cela m'a appris beaucoup mais je n'ai pas trouvé de réponse à cette question. Cordialement Jean Fred BROUARD avait prétendu : > Juanito a écrit : >> Bonjour, >> > > [...] > >> En fait, j'ai travaillé avant avec des gestionnaires de fichiers indexés >> dans lesquels il y a des ordres de lecture bloquantes et des déblocages. On >> peut donc lire et bloquer un enregistrement, faire plein de traitements, de >> saisie ... et à la fin mémoriser et débloquer. Si un autre poste essaie de >> faire une lecture blocante sur le même enregistrement cela renvoie un >> mesasge d'erreur. J'aimerais reproduire la même chose. > > D'ou vos question et votre erreur ! > > C'est le SGBDR qui fait tout cela de manière automatique... > > Commencez par apprendre comment fonctionne un SGBDR. A partir de là vous > aurez compris que vos questions n'ont aucun sens... > > Mon site web comme mes bouquins peuvent vous y aider ! > > A + |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
Juanito a écrit :
> Bonjour, > > Je comprends très bien que le Sgbdr gère les blocages durant les update. > Cependant ce que je voudrais c'est réserver une ligne d'une table pour > que les autres utilisateurs ne puissent pas l'utiliser. Même pendant > plusieurs minutes. > > A ouvre un client > B ouvre le même client la notion de client n'existe pas dans un SGBDR. On parle de table de lignes... Qu'est ce qu'un client ? Une ligne dans une table ??? Pour moi un client est un objet composé de plusieurs tables : table des personnes (générique) avec nom, prenom Table des "clients" (spécifique : héritage) avec remise et enseigne par exemple table des téléphones table des adressees table des mails ... Vous voudriez bloquer tout cela pour pendant 10 minutes juste pour une modif ? Nous ne vivons pas dans le même monde. Vous en êtes resté aux fichiers plat dans lequel figure tout un tas d'informations inutile. Votre volonté de vouloir reproduire le monde des fichiers plat est inutiles, stérile et dangereuse et fait mon bonheur en matière de conseil et d'audit. C'est là que je trouve le max de pognon à gagner parce que les applications deviennent catastrophiquement lente et son inexploitable dès qu'il y a un peu de volume. Donc il faut tout casser et produire un modèle relationnel. Soit quelques dizaines de jours de conseil, d'audit et cie facturé en moyenne 900 ¤ HT / j. Je vous renouvelle donc mon conseil : apprenez ce que sont les SGBDR... > A fait des modifs et les mémorise > B fait d'autres modifications et les mémorise > > En fait, lorsque A rappelle le client il ne voit plus ses modifs mais > celles effectuées par B. > > Soit le dernier qui mémorise gagne, soit on regarde par rapport à une > colonne timestamp mise à jour lors des mémorisations et on indique que > quelqu'un d'autre a fait des modifs entre temps et on refuse de mémoriser. > > Je préférerais indiquer un message à l'ouverture de la fiche du client il n'y a pas de "fiche " dans un SGBDR !!! > que quelqu'un d'autre est en train de le modifier et qu'il ne peut pas > le faire actuellement. > > Donc, si on ne peut pas bloquer une ligne je pourrais gérer ces > semblants de blocages par une table dans laquelle je mettrais le nom de > la table concernée, l'identifiant unique, l'utilisateur, la date et > l'heure ... Pour "bloquer" une ligne j'ajoute dans cette table et pour > "débloquer" je l'efface. Usine à gaz !!! > > Mais d'où ma remarque en cas de plantage ou de coupure de réseau. Cette > table contiendra des lignes considérées comme bloquées alors que cela > n'est pas le cas. Et oui... et comment faite vous pour distinguer les vrais blocage des faux ??? Si le client s'est reconnecté après un plantage par exemple ??? Vous aller auditer le réseau et avoir une table des trames TCP émises ??? Et si l'auditeur de trame réseau est lui même sur une banche défaillante du réseau ???????? ect, etc, ect... > > J'ai effectivement regardé votre site et parcouru un de vos livres. Cela > m'a appris beaucoup mais je n'ai pas trouvé de réponse à cette question. > Ne cherchez pas votre question n'a aucun sens ! > Cordialement > > Jean > > A + > > Fred BROUARD avait prétendu : >> Juanito a écrit : >>> Bonjour, >>> >> >> [...] >> >>> En fait, j'ai travaillé avant avec des gestionnaires de fichiers >>> indexés dans lesquels il y a des ordres de lecture bloquantes et des >>> déblocages. On peut donc lire et bloquer un enregistrement, faire >>> plein de traitements, de saisie ... et à la fin mémoriser et >>> débloquer. Si un autre poste essaie de faire une lecture blocante sur >>> le même enregistrement cela renvoie un mesasge d'erreur. J'aimerais >>> reproduire la même chose. >> >> D'ou vos question et votre erreur ! >> >> C'est le SGBDR qui fait tout cela de manière automatique... >> >> Commencez par apprendre comment fonctionne un SGBDR. A partir de là >> vous aurez compris que vos questions n'ont aucun sens... >> >> Mon site web comme mes bouquins peuvent vous y aider ! >> >> A + > > -- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation *********************** http://www.sqlspot.com ************************* |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
Bonjour,
Je suis tout à fait conscient que les sgbdr ne sont pas la même chose que des fichiers indexés mais l'utilisation qu'en font les utilisateurs est quand même la même. Si l'utilisateur préfère avoir un message indiquant qu'une autre personne est actuellement en train de modifier des informations dans la base plutôt que de faire ses modifications et les voir perdre lorsqu'il valide, cela me parait quelque part cohérent. Pas la peine de perdre du temps. Mon but est d'indiquer d'une manière ou d'une autre, avant que l'utilisateur commence ses modifications, que quelqu'un d'autre est déjà en train d'en faire. Que ce soit sur un Sgbdr ou des fichiers indexés, je ne vois pas pourquoi cela ne serait pas possible ? Les fichiers indexés peuvent très bien aussi être organisés comme vous l'indiquez avec des relations. C'est d'ailleurs comme cela que l'on fait généralement. On retrouve l'organisation que vous avez défini plus bas pour un "client". Jean Fred BROUARD a formulé la demande : > Juanito a écrit : >> Bonjour, >> >> Je comprends très bien que le Sgbdr gère les blocages durant les update. >> Cependant ce que je voudrais c'est réserver une ligne d'une table pour que >> les autres utilisateurs ne puissent pas l'utiliser. Même pendant plusieurs >> minutes. >> >> A ouvre un client >> B ouvre le même client > > la notion de client n'existe pas dans un SGBDR. On parle de table de > lignes... > > Qu'est ce qu'un client ? Une ligne dans une table ??? > > Pour moi un client est un objet composé de plusieurs tables : > table des personnes (générique) avec nom, prenom > Table des "clients" (spécifique : héritage) avec remise et enseigne par > exemple > table des téléphones > table des adressees > table des mails > .. > > Vous voudriez bloquer tout cela pour pendant 10 minutes juste pour une modif > ? > > Nous ne vivons pas dans le même monde. Vous en êtes resté aux fichiers plat > dans lequel figure tout un tas d'informations inutile. > > Votre volonté de vouloir reproduire le monde des fichiers plat est inutiles, > stérile et dangereuse et fait mon bonheur en matière de conseil et d'audit. > > C'est là que je trouve le max de pognon à gagner parce que les applications > deviennent catastrophiquement lente et son inexploitable dès qu'il y a un peu > de volume. > Donc il faut tout casser et produire un modèle relationnel. Soit quelques > dizaines de jours de conseil, d'audit et cie facturé en moyenne 900 ¤ HT / > j. > > Je vous renouvelle donc mon conseil : apprenez ce que sont les SGBDR... > > >> A fait des modifs et les mémorise >> B fait d'autres modifications et les mémorise >> >> En fait, lorsque A rappelle le client il ne voit plus ses modifs mais >> celles effectuées par B. >> >> Soit le dernier qui mémorise gagne, soit on regarde par rapport à une >> colonne timestamp mise à jour lors des mémorisations et on indique que >> quelqu'un d'autre a fait des modifs entre temps et on refuse de mémoriser. >> >> Je préférerais indiquer un message à l'ouverture de la fiche du client > > il n'y a pas de "fiche " dans un SGBDR !!! > >> que quelqu'un d'autre est en train de le modifier et qu'il ne peut pas le >> faire actuellement. >> >> Donc, si on ne peut pas bloquer une ligne je pourrais gérer ces semblants >> de blocages par une table dans laquelle je mettrais le nom de la table >> concernée, l'identifiant unique, l'utilisateur, la date et l'heure ... Pour >> "bloquer" une ligne j'ajoute dans cette table et pour "débloquer" je >> l'efface. > > Usine à gaz !!! > >> >> Mais d'où ma remarque en cas de plantage ou de coupure de réseau. Cette >> table contiendra des lignes considérées comme bloquées alors que cela n'est >> pas le cas. > > Et oui... et comment faite vous pour distinguer les vrais blocage des faux > ??? Si le client s'est reconnecté après un plantage par exemple ??? Vous > aller auditer le réseau et avoir une table des trames TCP émises ??? Et si > l'auditeur de trame réseau est lui même sur une banche défaillante du réseau > ???????? > ect, etc, ect... > >> >> J'ai effectivement regardé votre site et parcouru un de vos livres. Cela >> m'a appris beaucoup mais je n'ai pas trouvé de réponse à cette question. >> > > Ne cherchez pas votre question n'a aucun sens ! > >> Cordialement >> >> Jean >> >> > > A + > > >> >> Fred BROUARD avait prétendu : >>> Juanito a écrit : >>>> Bonjour, >>>> >>> >>> [...] >>> >>>> En fait, j'ai travaillé avant avec des gestionnaires de fichiers indexés >>>> dans lesquels il y a des ordres de lecture bloquantes et des déblocages. >>>> On peut donc lire et bloquer un enregistrement, faire plein de >>>> traitements, de saisie ... et à la fin mémoriser et débloquer. Si un >>>> autre poste essaie de faire une lecture blocante sur le même >>>> enregistrement cela renvoie un mesasge d'erreur. J'aimerais reproduire la >>>> même chose. >>> >>> D'ou vos question et votre erreur ! >>> >>> C'est le SGBDR qui fait tout cela de manière automatique... >>> >>> Commencez par apprendre comment fonctionne un SGBDR. A partir de là vous >>> aurez compris que vos questions n'ont aucun sens... >>> >>> Mon site web comme mes bouquins peuvent vous y aider ! >>> >>> A + >> >> |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
Salut Rudi :-)
"Rudi Bruchez" <rudi#nospam#at#babaluga.com> a écrit dans le message de news: Oa66rhrNIHA.1184@TK2MSFTNGP04.phx.gbl... > Bonjour, > > Juanito a écrit: > >> En fait, le développement que je fais est en Web et la crainte que j'ai >> est que s'il y a coupure de ligne ou un plantage qualconque, on se >> retrouve avec des lignes qui sont condidérées comme bloquées alors que >> cela n'est pas le cas. > > Désolé, mais là c'est du domaine de la science-fiction. Ce que tu veux > faire est utopique : dans un contexte web, il n'y a ni session, ni > plantage. Une page web est délivrée sur le client, et ensuite tout lien > avec le serveur est coupé. Si ton utilisateur clique sur le bouton > validation deux semaines après avoir chargé la page, que veux-tu qu'il > se passe ? Le "pseudo lock" peut simplement avoir une durée de vie. Ce délai passé, l'utilisateur perd son tour, l'enregistrement redevient modifiable par autrui. Notre utilisateur en validant son bouton au bout de deux semaines aura un beau message lui expliquant tout cela car avant de valider l'application vérifiera qu'il est bien le détenteur du lock et/ou que l'enregistrement n'a pas été modifié entre temps. J'ai déjà implémenté cela pour une appli web (Php/mySql) sans trop de souci. Il y a donc un processus qui se charge de "nettoyer" ces anciens locks. A+ Côme |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
Côme de Christen a émis l'idée suivante :
> Salut Rudi :-) > > "Rudi Bruchez" <rudi#nospam#at#babaluga.com> a écrit dans le message de news: > Oa66rhrNIHA.1184@TK2MSFTNGP04.phx.gbl... >> Bonjour, >> >> Juanito a écrit: >> >>> En fait, le développement que je fais est en Web et la crainte que j'ai >>> est que s'il y a coupure de ligne ou un plantage qualconque, on se >>> retrouve avec des lignes qui sont condidérées comme bloquées alors que >>> cela n'est pas le cas. >> >> Désolé, mais là c'est du domaine de la science-fiction. Ce que tu veux >> faire est utopique : dans un contexte web, il n'y a ni session, ni >> plantage. Une page web est délivrée sur le client, et ensuite tout lien >> avec le serveur est coupé. Si ton utilisateur clique sur le bouton >> validation deux semaines après avoir chargé la page, que veux-tu qu'il >> se passe ? > > Le "pseudo lock" peut simplement avoir une durée de vie. Ce délai passé, > l'utilisateur perd son tour, l'enregistrement redevient modifiable par > autrui. Notre utilisateur en validant son bouton au bout de deux semaines > aura un beau message lui expliquant tout cela car avant de valider > l'application vérifiera qu'il est bien le détenteur du lock et/ou que > l'enregistrement n'a pas été modifié entre temps. J'ai déjà implémenté cela > pour une appli web (Php/mySql) sans trop de souci. Il y a donc un processus > qui se charge de "nettoyer" ces anciens locks. > > A+ Côme Bonjour, Merci pour cette réponse. Effectivement un processus qui tourne continuellement et se charge de libérer les éléments restés "bloqués" trop longtemps est intéressant. Cordialement Jean |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
Salut Côme,
Côme de Christen a écrit: > Le "pseudo lock" peut simplement avoir une durée de vie. Ce délai passé, > l'utilisateur perd son tour, l'enregistrement redevient modifiable par autrui. > Notre utilisateur en validant son bouton au bout de deux semaines aura un beau > message lui expliquant tout cela car avant de valider l'application vérifiera > qu'il est bien le détenteur du lock et/ou que l'enregistrement n'a pas été > modifié entre temps. J'ai déjà implémenté cela pour une appli web (Php/mySql) > sans trop de souci. Il y a donc un processus qui se charge de "nettoyer" ces > anciens locks. C'est vrai, on peut faire comme ça. Mais comment choisir la durée de vie optimale ? 10 minutes, le temps d'aller déjeuner ? Jusqu'au lendemain. C'est plus facile en mode connecté quand on sait que la session sur la base est toujours ouverte. Cette contrainte prise en compte, pourquoi pas. -- Rudi Bruchez Consultant independant, MCDBA, MCITP, MCT http://www.babaluga.com/ http://rudi.developpez.com/ |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
bonjour, Juanito a écrit : > > Bonjour, > > Merci pour cette réponse. Effectivement un processus qui tourne > continuellement et se charge de libérer les éléments restés "bloqués" > trop longtemps est intéressant. dans ce cas inutile de prendre un SGDR client serveur. Préférez un SGBDR fichier comme paradox... (je vais faire plaisir à Come....) Cela sera beaucoup plus facile à implémenter.... A + > > Cordialement > |