首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >postgres数据库错误迫使事务重新启动

postgres数据库错误迫使事务重新启动
EN

Stack Overflow用户
提问于 2012-04-24 23:37:41
回答 1查看 941关注 0票数 4

TL;DR:在AR::中插入一个重复的连接表记录失败(因为一个唯一的约束),导致保存失败和回滚。不添加重复的联接表记录是可以的。不存钱是不好的。

我要把mysql应用程序移植到postgres..。我过去经常遵循这样的模式,在mysql-land中向DB添加连接表记录:

代码语言:javascript
复制
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

像这样被引用:

代码语言:javascript
复制
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

...in“异常处理和回滚”部分(请参阅警告)

基本上,#save启动了一个事务,重复的记录插入会导致数据库异常,从而使#save的事务无效,这是可悲的。

是否有一个更好的模式,可用于邮政-土地?

谢谢!

编辑:

我坚信在系列赛的保存事务中保持这种逻辑是有意义的.模式如下:

代码语言:javascript
复制
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.

..。它使我的控制器超小。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-26 22:34:14

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

当您使用命令SAVEPOINT 时,以后可以运行命令回滚到SAVEPOINT 以返回事务中的状态,并在保存点执行后忽略所有操作(包括错误)。

请看我在Continuing a transaction after primary key violation error的另一个答案,以获得更多的解释。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10307476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档