Testszenario: Zwei Flamerobin-Instanzen, damit man zwei separate Connections hat, die man parallel starten kann. Eine Quelltabelle tbl2 (num integer) mit 100000 Sätzen drin, und eine Zieltabelle tbl (num integer), leer. Ich hatte mir mal eine UDR sequencer geschrieben, um eine Reihe von Statements hintereinander oder parallel aus der Datenbank heraus ausführen zu können, eine Art Skriptplayer. Statements, die hintereinander ausgeführt werden sollen, werden darin mit einem '----' getrennt, ansonsten werden die Statements parallel ausgeführt. Mit der UDR hab ich getestet. Die serielle und parallele Skriptausführung kriegt man auf Anwendungsebene natürlich auch mit anderen Mitteln hin. Man muss halt nur bei den inserts für ausreichend action sorgen, sonst sieht man den Effekt nicht.
In jeder von den connections läuft also ein sequencer, der eine zählt immer schön nacheinander (die select count(*) werden nacheinander ausgeführt, siehe '----'), der andere sequencer schaufelt gleichzeitig zu den selects auf 10 connections parallel rein, jede von denen committet 100000 Sätze (nicht mehr, nicht weniger), Endergebnis in tbl müssten also 1 Mio Sätze sein, und, das ist der springende Punkt, Zwischenergebnisse der Zählung müssten Vielfache von 100000 sein:
con1:
Code: Alles auswählen
select * from sequencer('----',
'select count(*) from tbl;
----
select count(*) from tbl;
----
select count(*) from tbl;
----
select count(*) from tbl;
----
select count(*) from tbl;
----
select count(*) from tbl;
----
select count(*) from tbl;
----
select count(*) from tbl;
----
select count(*) from tbl;
----
select count(*) from tbl;
')
Code: Alles auswählen
select * from sequencer('----',
'insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
insert into tbl select num from tbl2;
')
Code: Alles auswählen
PART LINE TASK RESULT STATUS MESSAGE SELECTS INSERTS UPDATES DELETES TASK_TIME PART_TIME
1 1 select count(*) from tbl 0 ok [null] 1 0 0 0 484 484
2 1 select count(*) from tbl 0 ok [null] 1 0 0 0 484 484
3 1 select count(*) from tbl 0 ok [null] 1 0 0 0 485 485
4 1 select count(*) from tbl 7457 ok [null] 1 0 0 0 2828 2828
5 1 select count(*) from tbl 900136 ok [null] 1 0 0 0 1906 1906
6 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 781 781
7 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 719 719
8 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 641 641
9 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 625 625
10 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 562 562
Solange man Schreiben und Lesen schön hintereinander macht, erst füllen, dann lesen, hat man nie ein Problem. Aber wenn während einem Lesestatement committet wird, kann man ein Problem kriegen. Das dürfte auch der Grund sein, warum man bspw in ETL-Systemen kein Problem hat, denn dort organisiert man normalerweise den Ablauf selber. Da wird ja immer erst gefüllt und dann gelesen, nach selbst definierter Reihenfolge. Aber normalerweise wird nicht geschrieben, während etwas anderes liest. Und wenn, synct man das mit anderen Mitteln, wie bspw expliziten locks. Das hier kommt nur zum Tragen, wenn man ReadCommitted liest und währenddessen ohne weitere Koordination geschrieben und committet wird.
Mit ReadConsistency sieht der gleiche Test so aus:
Code: Alles auswählen
PART LINE TASK RESULT STATUS MESSAGE SELECTS INSERTS UPDATES DELETES TASK_TIME PART_TIME
1 1 select count(*) from tbl 0 ok [null] 1 0 0 0 500 500
2 1 select count(*) from tbl 0 ok [null] 1 0 0 0 422 422
3 1 select count(*) from tbl 0 ok [null] 1 0 0 0 500 500
4 1 select count(*) from tbl 300000 ok [null] 1 0 0 0 766 3328
5 1 select count(*) from tbl 800000 ok [null] 1 0 0 0 750 750
6 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 579 579
7 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 531 531
8 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 453 453
9 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 437 437
10 1 select count(*) from tbl 1000000 ok [null] 1 0 0 0 407 407
bfuerchau, das bedeutet für Deine Logik, dass Du nur die Stellen abklopfen musst, wo während einer ReadCommitted Leseaktion auf den von der Leseaktion betroffenen Daten von anderen TXen geschrieben und committet wird. Wenn das nie der Fall ist, hast Du nach wie vor kein Problem.
Martin, siehst Du eine Möglichkeit, in phpBB Tabellenanzeige zu unterstützen?
Grüße, Volker