1
0
mirror of https://github.com/meineerde/redmine.git synced 2026-01-09 09:01:31 +00:00

Prevent deadlocks by only locking the exact records we need to have locked (#25590).

Patch by Jens Kraemer.

git-svn-id: http://svn.redmine.org/redmine/trunk@16541 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang 2017-04-13 12:10:03 +00:00
parent 262f63b504
commit 4d5ddb0072

View File

@ -417,27 +417,33 @@ class Attachment < ActiveRecord::Base
reused = with_lock do
if existing = Attachment
.lock
.where(digest: self.digest, filesize: self.filesize)
.where('id <> ? and disk_filename <> ?',
self.id, self.disk_filename)
.first
existing.with_lock do
original_diskfile = self.diskfile
existing_diskfile = existing.diskfile
original_diskfile = self.diskfile
existing_diskfile = existing.diskfile
if File.readable?(original_diskfile) &&
File.readable?(existing_diskfile) &&
FileUtils.identical?(original_diskfile, existing_diskfile)
if File.readable?(original_diskfile) &&
File.readable?(existing_diskfile) &&
FileUtils.identical?(original_diskfile, existing_diskfile)
self.update_columns disk_directory: existing.disk_directory,
disk_filename: existing.disk_filename
self.update_columns disk_directory: existing.disk_directory,
disk_filename: existing.disk_filename
end
end
end
end
if reused
File.delete(original_diskfile)
end
rescue ActiveRecord::StatementInvalid, ActiveRecord::RecordNotFound
# Catch and ignore lock errors. It is not critical if deduplication does
# not happen, therefore we do not retry.
# with_lock throws ActiveRecord::RecordNotFound if the record isnt there
# anymore, thats why this is caught and ignored as well.
end