Ruby on rails Rails 4 ActiveRecord事务块-回滚条件

Ruby on rails Rails 4 ActiveRecord事务块-回滚条件,ruby-on-rails,activerecord,transactions,postgresql-9.1,Ruby On Rails,Activerecord,Transactions,Postgresql 9.1,您好,我正在使用ActiveRecords事务块使一组记录要么全部接受,要么不接受。 我将事务块包含在模型中,并从控制器调用整个函数: def self.write_atomic_union_sync Union.transaction do @sync=Sync.create(sync_date: DateTime.now, user_id: user_id) union_array.map do |t| Union.create(value2:

您好,我正在使用ActiveRecords事务块使一组记录要么全部接受,要么不接受。 我将事务块包含在模型中,并从控制器调用整个函数:

  def self.write_atomic_union_sync
   Union.transaction do
     @sync=Sync.create(sync_date: DateTime.now, user_id: user_id)
     union_array.map do |t|
        Union.create(value2: t[:value2], user_id:t[:user_id],value1: t[:value1],sync_id: @sync[:id])
        #sync.unions.create(t)
     end
   end
  end
我对
联合
有一些限制,以避免重复条目。 当我第一次发送测试数据时,带有union记录的同步对象被存储到数据库中。但是当我再次提交相同的数据时, 未保存联合,但写入同步

从中可以看出,在事务块中使用create方法是有效的,但我也尝试在前面的数组上调用
@sync.new
unions.new
,然后只放置
@sync.save等也没有多大成功

我认为这可能是因为unioncreate过程中没有显式的回滚异常。但是我不明白为什么。。 也许有人有有用的线索? 提前感谢大家

(1.2ms)  BEGIN
 Transaction Exists (0.7ms)  SELECT  1 AS one FROM "union" WHERE    ("union"."user_id" = 18 AND "union"."value1" =1111 AND "union"."value2" IS NULL) LIMIT 1

 SQL (0.7ms)  INSERT INTO "syncs" ("sync_date", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["sync_date","2016-01-13 21:04:48.175245"], ["user_id", 1], ["created_at", "2016-01-13 21:04:48.213958"], ["updated_at", "2016-01-13 21:04:48.213958"]]

 Transaction Exists (0.6ms)  SELECT  1 AS one FROM "transactions" WHERE ("transactions"."user_id" = 18 AND "transactions"."value1" =
 22222 AND "transactions"."value2" IS NULL) LIMIT 1
(27.4ms)  COMMIT

只有在引发异常时,事务块才会回滚。您希望使用在失败时产生异常的
create
版本:
create。这样,如果其中一个创建失败,它将引发一个异常,该异常将触发回滚。请注意,异常将传播到事务块之外,因此您必须在外部捕获它。尝试:

  def self.write_atomic_union_sync
    begin
      Union.transaction do
        @sync=Sync.create!(sync_date: DateTime.now, user_id: user_id)
        union_array.map do |t|
           Union.create!(value2: t[:value2], user_id:t[:user_id],value1: t[:value1],sync_id: @sync[:id])
           #sync.unions.create!(t)
        end
      end
    rescue
      # Handle the exception
    end
  end