FIX: Don't rescue `PG::UniqueViolation` within a transaction.

Also acquire a transaction per link instead of failing when
any of the links can't be processed.

This prevents ActiveRecord from rolling back the transaction
and the next SQL statement sent to PG will fail. This is
however hard to test as it only happens when there are
two competing process trying to process this method at the
same time.
This commit is contained in:
Guo Xiang Tan 2018-10-18 10:52:45 +08:00
parent 732b8655ea
commit 44eba0bb60
1 changed files with 16 additions and 17 deletions

View File

@ -111,9 +111,6 @@ SQL
def self.extract_from(post) def self.extract_from(post)
return if post.blank? || post.whisper? return if post.blank? || post.whisper?
added_urls = []
TopicLink.transaction do
added_urls = [] added_urls = []
reflected_ids = [] reflected_ids = []
@ -130,6 +127,8 @@ SQL
.reject { |_, p| p.nil? || "mailto".freeze == p.scheme } .reject { |_, p| p.nil? || "mailto".freeze == p.scheme }
.uniq { |_, p| p } .uniq { |_, p| p }
.each do |link, parsed| .each do |link, parsed|
TopicLink.transaction do
begin begin
url = link.url url = link.url
internal = false internal = false
@ -185,7 +184,7 @@ SQL
link_post_id: reflected_post.try(:id), link_post_id: reflected_post.try(:id),
quote: link.is_quote, quote: link.is_quote,
extension: file_extension) extension: file_extension)
rescue ActiveRecord::RecordNotUnique, PG::UniqueViolation rescue ActiveRecord::RecordNotUnique
# it's fine # it's fine
end end
end end