0

Ich habe das folgende Stück Code in Rails 3.2 + mySQL Anwendung:Rails Activeverbindungssitzung

ActiveRecord::Base.connection.execute("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED") 
ActiveRecord::Base.transaction do 
       @book = ActiveRecord::Base.connection.execute("select * from books limit 1") 
end 

Soweit ich die erste Aussage verstehen in der nächsten Transaktion innerhalb derselben Sitzung in sein führen wird " READ UNCOMMITTED "Isolation und dann Isolation wird auf den Standardwert zurückgesetzt.

Meine Fragen sind: Kann ich sicher sein, dass der Transaktionsblock immer in der gleichen Sitzung ausgeführt wird? Kann ich außerdem sicher sein, dass keine andere Transaktion in derselben Sitzung zwischen der ersten und der zweiten Anweisung stattfindet?

Ich habe versucht, Google für dieses Thema, aber da ich neu bei Rails bin, konnte ich keine Erklärung finden, die mir dies deutlich machen würde. Jede Hilfe wäre willkommen!

Vielen Dank!

Antwort

2

Ich denke, dass alle Ihre Fragen mit einer "YES" beantwortet werden können. Auch in Rails 3.2 werden die Verbindungen zur Datenbank von connection pool verwaltet. Dieser Pool stellt sicher, dass jedem Thread eine eigene dedizierte Verbindung zur DB zugewiesen wird. Der Pool weist Verbindungen zu Threads basierend auf ihren Thread-IDs zu, die für jeden Thread eindeutig sind. Lesen Sie die docs für weitere Informationen.

Also ich denke, es sollte nicht möglich sein, dass zwei Threads eine Verbindung und somit eine MySQL-Sitzung gleichzeitig teilen. Außerdem sollte gewährleistet sein, dass die Transaktion immer unter Verwendung derselben Verbindung (d. H. In derselben Sitzung) wie der Isolationsstufen-Einstellcode aufgerufen wird.

Übrigens, wenn Sie Rails 4 oder höher verwendet haben, können Sie das gleiche Verhalten nur mit der Methode transaction erreichen. Leider wird das Festlegen von Isolationsstufen in Rails 3 auf diese Weise nicht unterstützt. Das folgende Beispiel funktioniert daher in Ihrem speziellen Szenario nicht:

Book.transaction(:isolation => :read_uncommitted) do 
    @book = Book.first 
end 
# => SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
# BEGIN 
#  SELECT `books`.* FROM `books` ORDER BY `books`.`id` ASC LIMIT 1 
# COMMIT 
+0

Vielen Dank. Das hilft! Ja, es scheint, dass Rails 4 eine bessere Lösung dafür hat, aber leider kann ich jetzt nicht mit dem aktuellen Projekt nach Rails 4 migrieren. –

+0

Eine weitere Frage: Ist es notwendig, die Anweisung wie im Code in den Transaktionsblock zu schreiben? Funktioniert die Isolation noch korrekt, wenn ich nur sql-Anweisungen ohne Transaktionsblock ausführen möchte? –

+1

Ja, wie in [http://dev.mysql.com/doc/refman/5.7/en/set-transaction.html] erläutert, ist die Isolationseinstellung für den nächsten Transaktionsblock gültig. Auch das Festlegen einer Isolation auf Sitzungsebene ist nur für alle nachfolgenden Transaktionsblöcke gültig. – BoraMa