AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Firebird 3.0 in einer SP (Multiuser-Umfeld) ein Wert ändern
Thema durchsuchen
Ansicht
Themen-Optionen

Firebird 3.0 in einer SP (Multiuser-Umfeld) ein Wert ändern

Ein Thema von Kostas · begonnen am 8. Mai 2022 · letzter Beitrag vom 9. Mai 2022
Antwort Antwort
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.112 Beiträge
 
Delphi 12 Athens
 
#1

Firebird 3.0 in einer SP (Multiuser-Umfeld) ein Wert ändern

  Alt 8. Mai 2022, 16:19
Datenbank: Firebird • Version: 3.0 • Zugriff über: FIREDAC
Hallo Zusammen,

ich habe eine Tabelle mit zwei Felder PK + Chargen-Nummern und mehreren tauend Datensätzen.
Über eine SP wird der PK übergeben. Daraufhin wird die Chargen-Nummern über ein Update inkrementiert.
In sehr seltenen Fällen kommt es zu einem dead lock. Das Problem ist, ich habe keine Möglichkeit die Clients anzupassen um auf die exception zu reagieren. Es muss also innerhalb der SP passieren.

Hat jemand eine Idee?

Gruß Kostas
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.395 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Firebird 3.0 in einer SP (Multiuser-Umfeld) ein Wert ändern

  Alt 8. Mai 2022, 18:57
Hat jemand eine Idee?
viele, aber mit dem Code der SP müsste man nicht im trüben fischen....
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.112 Beiträge
 
Delphi 12 Athens
 
#3

AW: Firebird 3.0 in einer SP (Multiuser-Umfeld) ein Wert ändern

  Alt 8. Mai 2022, 19:43
Sorry,

so sieht meine Methode derzeit aus.

Code:
create or alter procedure GetNextCharge(ChargeID integer)
returns (
    NextCharcheNr integer)
as
declare variable vergleich1 integer;
declare variable vergleich2 integer;
begin

  Vergleich1 = 0;
  Vergleich2 = -1;

  while (Vergleich1 <> Vergleich2) do
  begin

    /* aktuelle CharcheNr abfragen */
    select CharcheNr
    from Chargen
    where ChargeID = :ChargeID
    into :Vergleich1;

    /* CharcheNr inkrementieren */
    Vergleich1 = Vergleich1 + 1;

    /* CharcheNr schreiben */
    update Chargen
       set CharcheNr = :Vergleich1
    where ChargeID = :ChargeID;

    /* zum Vergleich abfragen */
    select CharcheNr
    from Chargen
    where ChargeID = :ChargeID
    into :Vergleich2;

    /* wenn gleich raus ansonsten wiederholen */
    if (vergleich2 = vergleich1) then
    begin
      NextCharcheNr = :vergleich1;
      suspend;
    end
  end
end
  Mit Zitat antworten Zitat
knuut21

Registriert seit: 3. Mär 2010
Ort: Unna
21 Beiträge
 
RAD-Studio 2010 Ent
 
#4

AW: Firebird 3.0 in einer SP (Multiuser-Umfeld) ein Wert ändern

  Alt 9. Mai 2022, 05:54
Hallo Kostas,

Du kannst in dem Fall die Exception abfangen und ggf. im Ablauf entsprechend reagieren:

https://firebirdsql.org/file/documen...ef30-psql-when

BG

Knuut21
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
695 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Firebird 3.0 in einer SP (Multiuser-Umfeld) ein Wert ändern

  Alt 9. Mai 2022, 07:38
So als Konzept wie man das verhindern kann, wenn man das unter High Load realisieren muss:

1. Erstelle dir eine Tabelle mit chargennummer auf reserve (als zB sind da die nächsten x tausend verfügbaren chargennummer schon drin). Diese hat dann zB ein timestamp, wann die vergeben wurde
2. Wenn du eine Chargenummer brauchst, dann sucht deine prozedur über folgende weg eine heraus
3. übergeordnete sp ohne exception handling when any GetCharge
-diese ruft mit einer for select schleife alle chargen ab, die im vergeben timestamp null hat
4. über eine extra sp mit exception handling when any machst du das den eintrag
create procedure SetCharge(chargenr integer)
returns (res char(1))
as
begin
update charge set charge.vergeben=current_timestamp where charge.chargenr=:chargenr;
res='T';
when any do res='F';
end;
5. mit allen results die du in der GetCharge in der for select into schleife free chargenumer geholt hast machst du ein execute procedure SetCharge RETURNING_VALUES mit der chargenr als input sol lange bis die irgendwann man T zurück gibt, dann reicht ein break um deine for select schleife zu beenden, der timestamp ist für diese bisher frei charge gesetzt und egal ob unter high load jemand anders diese oder andere in lang laufenden transaktion auch setzt und evtl sogar rollback macht ist egal, weil keiner dadurch einen deadlock bekommt.

der code da oben ist einfach so runtergetippt, daher sicherlich hier und da evtl fehlerhaft, sollte aber zu schaffen sein, das umzusetzen
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
Firebird 5 Update und Know-how Workshop – 28.8.-29.08.2025 64546 Mörfelden - Walldorf

Geändert von IBExpert ( 9. Mai 2022 um 07:54 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
689 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Firebird 3.0 in einer SP (Multiuser-Umfeld) ein Wert ändern

  Alt 9. Mai 2022, 07:49
Es gibt da noch die globalen Variablen, die zur Connection oder Session gehören. Da kann man über die Tabelle auch die der anderen Connections/sessions sehen und auslesen. Könnte man anlegen, falls sie nicht da ist und löschen wenn man fertig ist. Und darüber dann sagen, welche Chargennummer man da gerade nutzt. wenn das mehrere Sessions sind, die sowas machen, dann einfach nur die größte einer fremdsession (also wo SessionId halt nicht die eigene ist) raussuchen und dann die nächste nehmen und selbst die Variable dann für die eigene Session anlegen. Und löschen, wenn man fertig ist.
  Mit Zitat antworten Zitat
Antwort Antwort


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 00:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz