Frage

Irgendwie bekomme ich diese immer am Freitag.

Meine frühere Frage war in Bezug auf das gleiche Problem, aber ich kann jetzt schmale Dinge ein wenig nach unten:

Ich habe mit diesem den ganzen Tag spielen und versuchen, einen Sinn zu machen. Ich habe eine Tabelle mit einem lock_version colum, spezifiziert so:

add_column :jobs, :lock_version, :integer, :default=>0

Und ich etwas tun, wie folgt aus:

foo = job.create!
first = Job.find(foo.id)
second = Job.find(foo.id)

Ich bestätige, dann die erste und die zweite auf das gleiche Objekt beziehen -. Ihre IDs gleich sind, und ich sehe, dass die Zeile in der Datenbank, um die mysql-Befehlszeilenprogramm mit

first.some_attribute_field = 'first'
second.some_attribute_field = 'second'
first.save
second.save

kein Problem bisher. Ich bekomme richtig ein Activerecord :: StaleObjectError Ausnahme. JEDOCH :

first = Job.find(foo.id)
second = Job.find(foo.id)
first.some_attribute_field = 'first'
second.some_attribute_field = 'second'
first.save
second.save

... und nichts passiert. Es stellt sich heraus, dass das einzige Mal, dass ich richtig (geworfen Ausnahme) Verhalten zu bekommen ist, wenn erste und zweite eine lock_version von 0. Nach dem ersten haben retten, aber es ist nie wieder 0. Was auf der Erde ist mit dieser?

Ich bin mit Rubin 1.8.6 und aktiven Datensatz 2.2.2

Danke ...

War es hilfreich?

Lösung

, wenn Sie anrufen first.save zweites Mal ist der Wert von some_attribute_field bereits gleich „zuerst“, Active weiß das, damit es nicht zu lock_version in der DB nicht aktualisiert erhöht erhalten. Die zweite speichern funktioniert wie der db wurde nie mit dem „ersten“ geändert.

Versuchen Sie, den Wert in dem zweiten Test auf etwas anderes als „ersten“ ändern, dass er anders ist, was in der db ist.

Andere Tipps

Ich bin kein Ruby-Typ, aber optimistische Sperren ist für mich vertraut, also werde ich versuchen Sie es zu debuggen, zu helfen.

nehme ich die zweite speichern aktualisiert tatsächlich die Datenbank. Wenn beide Objekte unterschiedliche lock_version haben UND lock_version in UPDATE verwendet, dann ist es einfach nicht möglich (UPDATE würde null Zeilen aktualisieren). So haben wir nur zwei Alternativen:

  • lock_version wird in Update-Anweisung oder falsch nicht verwendet
  • beiden Objekte haben die gleichen lock_version irgendwie

( tatsächlich gibt es eine dritte Alternative: beide save () sind in ihrem eigenen Geschäft, aber ich fühle mich Sie haben AUTOCOMMIT = true )

Können Sie aktuelle SQL-Anweisungen sichtbar machen? Die Update-Anweisung sollte wie lesen

... WHERE JOB_ID=123 AND LOCK_VERSION=8

Wenn Sie die tatsächlich Abfragen zur Hand haben werden, wäre es viel einfacher sein, einen Sinn zu geben, was los ist.

P. S. und eine weitere: in Ihrem Beispiel in einem anderen Thema, das Sie haben diese Aufgabe:

#<Job id: 323, lock: 8, worker_host: "second">

Die save () Aufruf kann je nach Container ignoriert werden, wenn die Eigenschaften nicht verändert werden verglichen Zeit zu laden. Ich weiß nicht, ob Active diese Optimierung hat oder aber nicht. Aber wenn es der Fall ist, dann zweite save () wird ignoriert, und das optimistische Sperren haben keine Chance zu treten.

Wie Vladimir gesagt, Ihr Test / Beispiel-Code ist ein wenig fehlerhaft. Zunächst nicht in der Datebase während der zweiten gespeichert bekommen sparen! (), Weil keine Attribute geändert haben. Siehe das folgende Beispiel:

foo = Account.create!

first = Account.find(foo.id)
first.cash = 100
first.save!


first = Account.find(foo.id)
first.cash = 100

puts "First lock before " + first.lock_version.to_s
first.save!
puts "First lock after " + first.lock_version.to_s

Dies erzeugt:

% script/runner another_tester.rb                               
First lock before 1
First lock after 1

Mit Ihrem Beispiel in der 2.3.2 Version von Schienen funktioniert, wie es mit einer Stale Objekt Ausnahme soll, wenn der zweite gespeichert (beiden Male!)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top