Thread Lock auf MySql-table notwendig? (12 answers)
Opened by gast at 2010-12-24 15:35

leo11
 2010-01-01 08:00
#143954 #143954
User since
2008-08-14
250 Artikel
BenutzerIn
[default_avatar]
2010-12-26T08:54:19 topeg
Man kann die Option "AutoCommit=>1" bei DBI setzen und damit ein sofortiges verteilen aller gemachten Aktionen fordern. Ansonsten werden die Änderungen erst allen anderen zur Verfügung gestellt, wenn man $dbh->commit() ausführt oder die Verbindung zur DB schießt.

Zum Verständnis habe ich folgenden Test gemacht. Hier der wesentliche Schnipsel:
Code (perl): (dl )
1
2
3
4
5
6
7
8
AutoCommit => 0,

my $sql = qq(insert into a values ('2'));
my $sth = $dbh->prepare($sql);
$sth->execute();
sleep(5);
$dbh->commit();
print "exit\n";

Die Spalte in die eingefügt werden sollte hat den Index Unique. Das Skript habe ich 2 mal gleichzeitig ausgeführt. Erst das mit dem sleep, dann ganz schnell in einer anderen Shell ohne das sleep. Letzteres bricht sofort mit der duplicate Meldung ab. Daraus folgt, dass das Insert gesehen wird, bevor es commited wurde. Wie ich mittlerweile weiß hat hat AutoCommit keinen Effekt bei nicht tranaktionsfähigen Engines wie MyISAM. Sie operieren immer im AutoCommit Modus. Wobei das zumindest das eine Buch sagt. Schaut man hier hat es zumindest in einem anderen Zusammenhang einen Effekt:
Quote
* Databases which don't support transactions at all

For these databases, attempting to turn AutoCommit off is a fatal error. commit and rollback both issue warnings about being ineffective while AutoCommit is in effect.
Mein Eindruck ist, das man letzlich genau in der Doku der benutzten Engine schauen sollte. Und natürlich testen.

topeg
Man sperrt eine Tabelle nur wenn man viele Aktionen auf diese anwendet bei deren Zwischenschritten man eine nicht funktionstüchtige Tabelle hat. Wenn es nur um das einfügen/ändern geht, so passt die DB schon darauf auf dass die Einträge so schnell wie möglich allen anderen Zugreifenden zur Verfügung stehen.

Mal ein dummes Beispiel wo man sperren würde.
Man habe eine Tabelle mit einer ID und einem Namen. Bei einer Alphabetischen Sortierung der Namen sollen die IDs aufeinander folgend aufsteigend sein. Das bedeutet bei jedem eingefügten Namen müssen alle IDs neu vergeben werden, dass lässt sich ohne weiteres nicht mit einer atomaren Aktion machen (eine nicht aufteilbare Aktion) Bis alle IDs vergeben sind ist die Tabelle nicht funktionstüchtig. (keine IDs oder doppelte IDs vorhanden) Also muss die Tabelle bis zum Abschluss der ID-Vergabe gesperrt werden, damit es zu keinen fehlerhaften Abfrageergebnissen kommt.

Bei einem einfachen einfügen/ändern eines Datensatzes braucht man das nicht, das diese Aktionen atomar sind.
Diese Dinge hängen stark von der benutzten DB/DB-Version und der Engine ab. Genauer kann man das hier nachlesen: MySql Man braucht nur in seltenen Fällen extern locken. MySql nimmt einem viele schwierige Themen ab.

View full thread Lock auf MySql-table notwendig?