gpt4 book ai didi

postgresql - postgres 数据库错误强制事务重新启动

转载 作者:行者123 更新时间:2023-11-29 11:35:34 25 4
gpt4 key购买 nike

TL;DR:在 AR::Base 保存事务中插入重复的连接表记录失败(由于唯一约束)导致保存失败并回滚。不添加重复的连接表记录就可以了。不保存是不好的。


我正在将一个 mysql 应用程序迁移到 postgres...我曾经在 mysql-land 中遵循类似这样的模式来将连接表记录添加到数据库中:

class EventsSeries < ActiveRecord::Base
# UNIQUE KEY `index_events_series_on_event_id_and_series_id` (`event_id`,`series_id`)
belongs_to :event
belongs_to :series
end

class Series < ActiveRecord::Base

has_many :events_series
before_validation :add_new_event

private

def add_new_event
# boils down to something like this
EventSeries.new.tap do |es|
es.event_id = 1
es.series_id = 1
begin
es.save!
rescue ActiveRecord::RecordNotUnique
# Great it exists
# this isn't really a problem
# please move on
end
end
end
end

这样调用:

Series.first.save 
# should not blow up on duplicate join record, cause i don't care

然而,postgres 对此大发雷霆。这里有一个很好的解释:

http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

...在“异常处理和回滚”部分(参见警告)

基本上#save启动了一个事务,重复记录insert导致数据库异常,使#save的事务失效,很sadface。

是否有更好的模式可以用于 postgres-land?

谢谢!


编辑:

我坚信将此逻辑保留在 Series 的保存事务中是有意义的……模式如下所示:

s = Series.new
s.new_event_id = 123 # this is just an attr_accessor
s.save # callbacks on Series know how to add the new event.

...它让我的 Controller 变得超小。

最佳答案

如果您在事务中并且要从错误中恢复并避免使整个事务无效,则必须使用保存点。

当您使用命令SAVEPOINT some-label时,您可以稍后运行命令ROLLBACK TO SAVEPOINT some-label返回到事务中的那个状态并忽略所有采取保存点后的操作(包括错误)。

请在 Continuing a transaction after primary key violation error 查看我的其他答案以获得更透彻的解释。

关于postgresql - postgres 数据库错误强制事务重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10307476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com