]> source.dussan.org Git - redmine.git/commitdiff
prevent issue tree hierarchy is broken in race conditions (#6579)
authorToshi MARUYAMA <marutosijp2@yahoo.co.jp>
Tue, 25 Feb 2014 06:49:53 +0000 (06:49 +0000)
committerToshi MARUYAMA <marutosijp2@yahoo.co.jp>
Tue, 25 Feb 2014 06:49:53 +0000 (06:49 +0000)
awesome_nested_set 2.1.6 uses lock.
Issue model uses as same way.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12925 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/issue.rb

index 2c2e9f087f82d5951397fa7627a006c2dd767312..c8d45d7d769480945bf41623d640039d12bca071 100644 (file)
@@ -1312,13 +1312,19 @@ class Issue < ActiveRecord::Base
         move_to_right_of(root)
       end
       old_root_id = root_id
-      self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id )
-      target_maxright = nested_set_scope.maximum(right_column_name) || 0
-      offset = target_maxright + 1 - lft
-      Issue.where(["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt]).
-        update_all(["root_id = ?, lft = lft + ?, rgt = rgt + ?", root_id, offset, offset])
-      self[left_column_name] = lft + offset
-      self[right_column_name] = rgt + offset
+      in_tenacious_transaction do
+        @parent_issue.reload_nested_set if @parent_issue
+        self.reload_nested_set
+        self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id)
+        cond = ["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt]
+        self.class.base_class.select('id').lock(true).where(cond)
+        target_maxright = nested_set_scope.maximum(right_column_name) || 0
+        offset = target_maxright + 1 - lft
+        Issue.where(cond).
+          update_all(["root_id = ?, lft = lft + ?, rgt = rgt + ?", root_id, offset, offset])
+        self[left_column_name]  = lft + offset
+        self[right_column_name] = rgt + offset
+      end
       if @parent_issue
         move_to_child_of(@parent_issue)
       end