2016-01-13 2 views
0

Привет, я использую блок транзакций ActiveRecords, чтобы сделать кучу записей либо принятыми, либо нет. я включил блок транзакции внутри моей модели и вызвать целую функцию от контроллера:Rails 4 Блок транзакций ActiveRecord - критерии отката

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, чтобы избежать дублирующихся записей. Когда я отправляю свои тестовые данные в первый раз, объект синхронизации с записями объединения будет сохранен в базе данных. Однако, когда я снова фиксирую одни и те же данные, профсоюзы не сохраняются, но синхронизация записывается.

С Ruby API guide действительно использовать метод создания внутри блока транзакции, но я также попытался с вызовом @sync.new и unions.new по массиву перед тем, а затем положить только @sync.save! и т.д. внутри блока транзакции без особого успеха либо.

Я думаю, что это возможно потому, что исключение исключений ROLLBACK отсутствует из процедуры создания объединения. Но я не могу понять, почему .. может быть, у кого-то есть полезная подсказка? Спасибо всем!

(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 

ответ

0

Блок транзакций будет откатываться только в случае возникновения исключения. Вы хотите использовать версию 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 
+0

безупречный !!! Большое спасибо :) – theDrifter

Смежные вопросы