Clone objects before saving in case of a retry

If a deadlock occurs then the transaction will be retried so we
need to make sure that the object will still be dirty so that it
will be saved again during the retry but that the version won't
be incremented a second time.
This commit is contained in:
Tom Hughes 2016-11-28 20:31:04 +00:00
parent ebf443d22d
commit e5834016fd
3 changed files with 21 additions and 10 deletions

View file

@ -232,10 +232,14 @@ class Node < ActiveRecord::Base
def save_with_history!
t = Time.now.getutc
self.version += 1
self.timestamp = t
Node.transaction do
self.version += 1
self.timestamp = t
save!
# clone the object before saving it so that the original is
# still marked as dirty if we retry the transaction
clone.save!
# Create a NodeTag
tags = self.tags

View file

@ -281,15 +281,19 @@ class Relation < ActiveRecord::Base
private
def save_with_history!
t = Time.now.getutc
self.version += 1
self.timestamp = t
Relation.transaction do
# have to be a little bit clever here - to detect if any tags
# changed then we have to monitor their before and after state.
tags_changed = false
t = Time.now.getutc
self.version += 1
self.timestamp = t
save!
# clone the object before saving it so that the original is
# still marked as dirty if we retry the transaction
clone.save!
tags = self.tags.clone
relation_tags.each do |old_tag|

View file

@ -255,6 +255,9 @@ class Way < ActiveRecord::Base
def save_with_history!
t = Time.now.getutc
self.version += 1
self.timestamp = t
# update the bounding box, note that this has to be done both before
# and after the save, so that nodes from both versions are included in the
# bbox. we use a copy of the changeset so that it isn't reloaded
@ -263,9 +266,9 @@ class Way < ActiveRecord::Base
cs.update_bbox!(bbox) unless nodes.empty?
Way.transaction do
self.version += 1
self.timestamp = t
save!
# clone the object before saving it so that the original is
# still marked as dirty if we retry the transaction
clone.save!
tags = self.tags
WayTag.delete_all(:way_id => id)