From 4162d8ec6b68d6ac8e348f8a8e73fab4e0ca8bfa Mon Sep 17 00:00:00 2001 From: Toshi MARUYAMA Date: Tue, 25 Feb 2014 06:54:40 +0000 Subject: prevent issue tree hierarchy is broken in race conditions (#6579) awesome_nested_set 2.1.6 uses lock. Issue model uses as same way. git-svn-id: http://svn.redmine.org/redmine/trunk@12927 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/issue.rb | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'app/models') diff --git a/app/models/issue.rb b/app/models/issue.rb index 2c2e9f087..c8d45d7d7 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -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 -- cgit v1.2.3