AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhindern
Thema durchsuchen
Ansicht
Themen-Optionen

Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhindern

Offene Frage von "pertzschc"
Ein Thema von Zottel · begonnen am 12. Okt 2004 · letzter Beitrag vom 21. Sep 2005
Antwort Antwort
Seite 1 von 2  1 2      
Zottel
(Gast)

n/a Beiträge
 
#1

Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhindern

  Alt 12. Okt 2004, 16:19
Hallihallo!

Ich steh grad ein wenig auf dem Schlauch.
Ich habe clients, die auf eine MSSQL-tabelle zugreifen.
Da drin befindet sich ein Tupel, der einen Integer-Wert beinhaltet.
Die Clients sollen sich diesen Wert holen und ihn um 1 erhöhen.
Das darf aber nicht gleiczeitig geschehen, weil evtl. sonst beide den gleichen wert holen, und beide ihn um 1 erhöhen. also letztendlich um 2
Ich habe keine ahnung,m wie ich das mit den beiden syncronen zugriffen simulieren soll.
Gibt es eine möglichkeit, den gleichzeitigen zugriff schon mit einem SQL-Befehl zu verhindern?
Oder reicht es schon, den befehl in einen BEGIN TRAN / COMMIT TRAN -Block einzuschließen?
Erstmal habe ich es jetzt über eine paar umwege gelöst, was aber eher provisorisch ist.

Vielen dank schonmal
Jens
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#2

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 12. Okt 2004, 17:13
Was ist denn Sinn dieses Integerwertes. In welchem Kontext wird der denn geändert.

Dem Server kannst du nicht sagen "Junge, jetzt pause mal bis du mit mir fertig bist, und dann bedienst du den nächsten Client". Das ist ja auch nicht Sinn eines SQL-Servers.

Der Lösungsweg führt wahrscheinlich über Transaktionen. Die sind erst mal für die anderen Clients unsichtbar, bis du ein Commit an die DB schickst.
  Mit Zitat antworten Zitat
Zottel
(Gast)

n/a Beiträge
 
#3

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 12. Okt 2004, 17:53
Aber genau das muss ich ihm sagen.
Ein integerwert darf nicht zweimal an einen client gehen.
Sozusagen ein GetAndInc eines Wertes.
Eine geschlossene Transaktion, die den Tupel solange sperrt, bis dieser fertig ausgelesen und incrementiert ist.
Ich weiss, das es nicht der sinn einen SQL servers ist
Ich glaube ich beschäftige mich mal mit dem sperren von tabellen

Danke,
jens
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 12. Okt 2004, 18:22
Muss der Integer Wert in einer Tabelle gespeichert sein. Vielleicht kannst du auch über globale Variablen gehen ( @@Wert ). Habs aber noch nie probiert.
  Mit Zitat antworten Zitat
Zottel
(Gast)

n/a Beiträge
 
#5

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 13. Okt 2004, 17:44
Hmm.. nee.. das funzt so net.

was ist,wenn ich folgenden sql befehl habe:

BEGIN TRAN
SELECT wert FROM t_werte where bezeichner like 'testwert' with (xlock)
UPDATE t_werte SET wert=wert+1 bezeichner like 'testwert'
COMMIT TRAN

kann ein anderer Client zwischen dem select und Update den wert ebenfalls holen? oder ist der dann gespeert?
Ist der für die komplette transaktion gesperrt?

das wäre die möglichkeit, die ich eigendlich suche.

gruss
jens
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#6

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 13. Okt 2004, 17:53
durch das update setzt du nur in deiner Transaktion einen neuen Wert. Also auch nach dem Update liest ein anderer User nicht den für dich aktuellen Wert, sondern den gleichen wie du auch gelesen hast. Erst durch das Commit wird die Tabelle t_werte endgültig aktualisiert, und auch die anderen Benutzer kriegen davon mit.
  Mit Zitat antworten Zitat
Zottel
(Gast)

n/a Beiträge
 
#7

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 11. Nov 2004, 18:43
Hi ihr,
kleiner Nachtrag:

mit dem Befehl
BEGIN TRAN
SELECT wert FROM t_werte where bezeichner like 'testwert' with (rowlock)
UPDATE t_werte SET wert=wert+1 bezeichner like 'testwert'
COMMIT TRAN

klappt das einwandfrei. während der transaktion ist die zeile gesperrt und es kommt nicht vor, das andere clients den selben wert auslesen, ohne das er hochgezählt wird.

Gruss Jens
  Mit Zitat antworten Zitat
pertzschc

Registriert seit: 29. Jul 2005
Ort: Leipzig
309 Beiträge
 
Delphi 12 Athens
 
#8

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 21. Sep 2005, 15:45
Zitat von Zottel:
mit dem Befehl
BEGIN TRAN
SELECT wert FROM t_werte where bezeichner like 'testwert' with (rowlock)
UPDATE t_werte SET wert=wert+1 bezeichner like 'testwert'
COMMIT TRAN

klappt das einwandfrei. während der transaktion ist die zeile gesperrt und es kommt nicht vor, das andere clients den selben wert auslesen, ohne das er hochgezählt wird.
Wie würdest Du es machen, wenn die Zeile noch nicht in der Tabelle enthalten ist, also mit INSERT erst in
die Tabelle eingefügt werden muss. Meines Wissens schlägt dann das UPDATE fehl.

Gruß,
Christoph
  Mit Zitat antworten Zitat
Zottel
(Gast)

n/a Beiträge
 
#9

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 21. Sep 2005, 17:15
hi pertzschc,

in dem fall würde ich warscheinlich anstatt einem RowLock ein XLock nehmen.
sowas in der art wie:

begin tran
insert into TestTabelle with (XLOCK) (testwert) VALUES (1)
commit tran

Allerdings weiss ich nicht, wie sich das ding dann in einem fehlerfall verhält.
müßte man mal ausprobieren.


//edit: klammern vergessen
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#10

Re: Gleichzeitigen Zugriff bei MSSQL auf einen Tupel verhind

  Alt 21. Sep 2005, 17:38
Brauchst du vielleicht einen Generator ?
Ein Generator liefert einen eindeutigen Integerwert zurück.
Dabei wird sichergestellt, dass kein anderer Client den gleichen Wert erhalten kann.
MSSQL unterstützt von sich aus keine Generatoren (Firebird kann's aber
http://www.fingerbird.de/generatorgu...erators_stored );
diese lassen sich aber nachbauen.
Zuerst die Tabelle Generators:
SQL-Code:
CREATE TABLE [dbo].[Generators] (
   [IdGenerator] [varchar] (20) NOT NULL ,
   [CurrentValue] [int] NOT NULL
) ON [PRIMARY]
GO
Dann noch folgende SP:
SQL-Code:
Create procedure generator_id ( @IdGenerator varchar(20))
as
begin
      declare @ID integer

      SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
      BEGIN TRANSACTION SP_GEN_ID

      select @ID = CurrentValue from Generators where IdGenerator =@IdGenerator
      IF @@ERROR <> 0 GOTO LBL_ERROR
      update Generators set CurrentValue =CurrentValue + 1 where IdGenerator=@IdGenerator
      IF @@ERROR <> 0 GOTO LBL_ERROR

      COMMIT TRANSACTION SP_GEN_ID
      return @ID

LBL_ERROR:
      ROLLBACK TRANSACTION SP_GEN_ID
      return 0
end
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:46 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz