AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Thread freigeben, wenn er festklebt :)

Ein Thema von MyRealName · begonnen am 31. Mär 2015 · letzter Beitrag vom 28. Sep 2017
Antwort Antwort
Seite 1 von 3  1 23   
Benutzerbild von MyRealName
MyRealName

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

Thread freigeben, wenn er festklebt :)

  Alt 31. Mär 2015, 18:39
Delphi-Version: 5
Hallo,

hab mal eine Frage...
Ich lagere gerade einige DB Prozesse in einen service aus, welcher wiederrum auf dem Server läuft. Dazu habe ich mir einen ThreadPool gebaut und Datenbanken klassifiziert, ob sie in einem Thread allein laufen (weil viel genutzt), oder ob sie ihn sich mit 3 oder 15 DBs teilen (Also max DBs ist 1, 4 oder 16 bis jetzt)
In denen führe ich eine stored procedure aus (über UniDAC), welche dann entscheidet, welche Aufgabe erledigt werden soll. Soweit, so gut.. das geht auch alles sehr schön und flink, auch die Erzeugung und Schliessung von Threads.
Jetzt kommt der theoretische Fall den ich bedenken muss :

Wenn die Stored Procedure aus irgendwelchen Gründen mal nicht zurück kommt, klebt sich der thread ja fest (und wenn er geshared ist mit anderen DBs, wird bei denen ja auch nichts mehr ausgeführt). Dazu habe ich ein Ping Pong eingebaut über Windows Nachrichten, welche alle 30 sekunden die threads fragt, ob sie noch leben. Heisst, wenn ein thread nicht antwortet, schlägt der timer nach 30 sekunden wieder auf und erkennt, dass der thread nicht geantwortet hat und soll ihn beenden und neu erstellen (habe alle information, um ihn neu zu starten).

Problem ist, beim Thread.Free bleibt alles stehen dann. wenn threads sich normal dort beenden (weil der letzte User raus ist), geht alles toll. Aber ich kann ja nicht Terminated auf true setzen, weil der thread ja blockiert ist.

Gibt es ideen ?


Code:
    Try
      UsageLevel := vtThreadDataUsageLevel.Value;
      OldThreadId := vtThreadDataThreadId.Value;
      EnterCriticalSection(aCriticalSection);
      FpThread := TDatabaseConnectionThread(Pointer(vtThreadDataaObj.AsInteger));
      FpThread.Free;
      LeaveCriticalSection(aCriticalSection);
    except
      On E: Exception Do
        CodeSite.Send( csmLevel1, 'Error deleting thread', E.Message);
    End;
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#2

AW: Thread freigeben, wenn er festklebt :)

  Alt 31. Mär 2015, 18:54
Um die beste Möglichkeit direkt auszuschließen: Die UniDAC-Komponenten bieten keinen Timeout für einen Request an?
Leider musst du davon ausgehen, das die Datenbankverbindung (oder die gesamte Bibliothek) nicht mehr korrekt funktioniert kann, wenn du den ausführenden Thread zwischendurch einfach abschießt

Außerdem springt mir ins Auge, dass du deine Critical Section nie freigibst, wenn im Folgenden ein Fehler auftritt:
Delphi-Quellcode:
      FpThread := TDatabaseConnectionThread(Pointer(vtThreadDataaObj.AsInteger));
      FpThread.Free;
Was schützt die CS denn genau?

Geändert von BUG (31. Mär 2015 um 18:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Thread freigeben, wenn er festklebt :)

  Alt 31. Mär 2015, 18:59
Außerdem springt mir ins Auge, dass du deine Critical Section nie freigibst, wenn im Folgenden ein Fehler auftritt:
Delphi-Quellcode:
      FpThread := TDatabaseConnectionThread(Pointer(vtThreadDataaObj.AsInteger));
      FpThread.Free;
Was schützt die CS denn genau?
Ich vermute, dass ist eine CS die als Argument übergeben wird (wegen aCriticalSection)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.014 Beiträge
 
Delphi 12 Athens
 
#4

AW: Thread freigeben, wenn er festklebt :)

  Alt 31. Mär 2015, 19:07
Was heißt denn hängen/festkleben?
Bzw. warum hängt der denn?

Gerade in einem Service, vorallem wenn der länger läuft, sollte man beser alles ordentlich beenden und vorallem die Resourcen richtig freigeben, was durch Abschießen praktisch nicht möglich ist.


PS: Da du natürlich keine Resourcenschutzblöcke verbaut hast, gibt es bei einer Exception einen geilen Deadlock in deiner aCriticalSection.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

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

AW: Thread freigeben, wenn er festklebt :)

  Alt 31. Mär 2015, 19:18
festkleben heisst, dass eine Stored Proc nie wieder kommt und UniDAC für immer wartet. Das blockiert den Thread.

aCriticalSection ist eine globale variable im MainThread, welche beim erstellen des Services erzeugt wird und auch wieder freigegeben wird.
Und die Option des Abschiessens ist nicht... ähm... optimal, aber eine stored proc in dem Kontext sollte nie länger als 1-3 Sekunden dauern, wenn es länger dauert, dann ging was unerwartetes schief und ich muss das mit einbedenken.
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#6

AW: Thread freigeben, wenn er festklebt :)

  Alt 31. Mär 2015, 20:29
Wie kann denn eine SP nie zurückkommen? Die Frage sollte mit 'NIE' beantwortet werden.
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

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

AW: Thread freigeben, wenn er festklebt :)

  Alt 31. Mär 2015, 21:43
Eine option ist zum Bsp. die WAIT Transaction, die nicht einen lock conflict herbeiführt, sondern wartet bis die andere ihre updates abgschlossen hat. Hatte Falle wo niemand mit einer DB verbunden war und ich die SP nie zurück kam in der WAIT transaction. eine NO_WAIT brachte sofort einen lock conflict, obwohl niemand dort war. Ein Neustart von Firebird brachte die Lösung.

UniDAC hat keine Option, "normal" zu beenden mit TimeOut oder so. UniDAC blockiert immer den ganzen Thread.
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#8

AW: Thread freigeben, wenn er festklebt :)

  Alt 1. Apr 2015, 07:38
Mein Beitrag ging in die Richtung: Dann würde ich diese Implementierung überdenken bzw. dafür sorgen, das eine Query/SP nie hängt. Das sollte mit FB doch zu machen sein.

"Abschießen" o.ä. ist jedenfalls die unsauberste aller Implementierungsoptionen.

Alternativ kann man sich asynchron verbinden und die Verbindung bei Zeitüberschreitung beenden. Ob das mit UniDAC geht, weiß ich nicht.

Edit: Ich verstehe zwar nicht genau, was der TE mit 'DB' meint, und das ein Thread sich DBs teilt, aber grundsätzlich würde ich das nicht so lösen, sondern über einen Connectionpool. Pro Anfrage ein Thread, die sich aus dem Pool bedienen. Das löst das Problem zwar nicht, dürfte aber um vieles einfacher sein.

Geändert von Dejan Vu ( 1. Apr 2015 um 07:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

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

AW: Thread freigeben, wenn er festklebt :)

  Alt 1. Apr 2015, 14:22
Es ist ein Connection Pool, aber ich mache nicht pro Anfrage ein thread, weil das viel zu lange dauert. Manchmal habe ich nach einer Kostenneuberechnung im System ein paar tausend Dokumente neu zu buchen in der Buchhaltung (deren Bewegung vom Inventarkonto zum Ausgabenkonto). Pro Dokument kann das in total schonmal 1-2 Sekunden dauern. Wenn ich für jede von diesen Aufgaben enen neuen Thread machen wurde, wäre der Overhead an Zeit einfach zu gross. Ich kriege ja schon Mecker vom Chef, weil ich die nicht im Block abarbeite, sondern ene transaktion für jede mache und mir in Sammelthreads sogar noch zeit für andere DBs nehme

Klar, die beste Lösung ist wenn die SP nie hängt, aber das schafft man auch nur zu 99%. Da kommen viel Faktoren mit rein. Versuche nur, an alles zu denken und auch die 1% abzudecken
Unsere DB hat knapp 400 stored procs und ein paar hundert Trigger. In Kombination mit den Daten kann es da zu seltsamen zusammenspielen kommen, die man nicht im vorraus sieht.
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#10

AW: Thread freigeben, wenn er festklebt :)

  Alt 1. Apr 2015, 17:20
Oh.. Also 'as is'. Na ja. Dann muss man es eben so machen.

Wie wäre es mit Workerthreads, die eine Jobliste abarbeiten? Einen Workerthreadpool gibts hier im Forum.

Falls es untergegangen sein sollte: Imho sollte nicht der Thread abgeschossen werden (geht nicht, nur schlafenlegen geht), sondern die Connection. Und das sollte FB drauf haben. Oder Du lässt dir dir PID von der Connection geben (oder wie auch immer das bei FB heißt) und killst Du dann (wenn das bei FB geht).
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 14:12 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