Hallo der henry,
Fehler gefunden .. die Intervalzeit zum Aufruf der Funktion war zu kurz d.h. Es wurde vor dem beenden der Funktion, die Funktion erneut aufgerufen
Uff, hast Du die Funktion einmal pro Sekunde aufgerufen oder läuft sie so lange?!
Die writeplcdatapoints-Funktion habe ich, glaube ich, bisher nie von innen gesehen. Sie bekommt einen Variablennamen und einen Setpoint, und dann? Du hast einmal eine andere Funktion gezeigt, write_plcactvalue_database, die bekommt ein String/String Dictionary.
Wie ist der genaue Datenfluss? Den hast Du vielleicht mal beschrieben, aber ich finde es nicht wieder. Überschreibst Du die gelesenen Sätze? Oder schreibst Du sie nur woanders hin und löschst sie dort, wo Du sie gelesen hast?
Wichtig ist auch: Welches Statement wirft diesen Fehler? Ein Update oder ein Delete?
Und jetzt etwas grundsätzliches. Eine Transaktion hindert andere Prozesse nur ausnahmsweise daran, die Sätze zu ändern, die Du in der Transaktion gelesen hast. Der Hauptzweck einer Transaktion ist, dass ein Set von Updates ganz oder gar nicht ausgeführt wird. Für den Leseschutz kommt der Isolation Level ins Spiel. Dazu haben wir nichts im Wiki, ich muss den Abschnitt zu Datenbanken wohl mal erweitern.
Defaultwert für den Isolation Level ist in MySQL "Repeatable Read", d.h. der DB-Server macht einen Snapshot von den Sätzen, die Du in der Transaktion liest, und wenn Du den gleichen Satz nochmal liest, bekommst Du den gleichen Inhalt wie beim ersten Mal. Das heißt aber nicht, dass der Satz in der DB unverändert ist. Dafür musst Du einen Lock setzen und dafür gibt's zwei Wege.
Erstens statementweise im SELECT Statement, entweder durch Angabe von "LOCK IN SHARE MODE", was das Schreiben durch andere Connections verhindert, oder durch Angabe von "FOR UPDATE", was auch das Lesen verhindert. Guckst Du als erstes hier und folgst dann den Links.
Zweitens geht das auch für die ganze Transaktion, durch SET TRANSACTION. Der Isolation Level "Serializeable" setzt automatisch Shared Locks, die das Schreiben durch andere Transaktionen verhindern. Er verhindert aber nicht, dass eine andere Transaktion eine Shared-Sperre setzt, die Dich dann doch noch am Schreiben hindert. Das geht nur durch Angabe von "FOR UPDATE" beim SELECT.
Die Locks werden am Ende der Transaktion freigegeben.
WARNUNG
Jeder Lock hat das Potenzial für einen Deadlock! Einfaches Beispiel: Transaktion A liest und sperrt den Satz 1 und möchte dann Satz 2 lesen. Transaktion B (die zu einer anderen Connection gehört) liest und sperrt zuerst Satz 2 und möchte dann Satz 1 lesen. Wenn das ziemlich gleichzeitig passiert, warten beide Transaktionen gegenseitig aufeinander und brechen nach einer gewissen Wartezeit mit einem Timeout ab.
Wer also DB-Sperren setzt und mit parallelen Connections rechnet, muss seine Zugriffe gut planen, um Deadlocks möglichst zu vermeiden.
Die Frage ist also, warum überhaupt einer der von Dir gelesenen Sätze verändert wurde, wie war da der Ablauf und das Timing? Um sowas in einem Langläufer aufzuklären, muss man ggf. gründlich loggen.
Rolf
sumpsi - posui - obstruxi