Используя гем Neo4jrb, возможно ли использовать одну транзакцию для нескольких блоков

Используя https://github.com/neo4jrb/neo4j (8.x), я знаю, что можно выполнить несколько запросов внутри одной транзакции, например, так

person = Person.find_by(id: person_id)

Neo4j::ActiveBase.run_transaction do |tx|
  person.update(name: 'New name')
  person.update(number: 1)
end

Но можно открыть транзакцию, а затем использовать эту же транзакцию в нескольких блоках. Что-то вроде:

person = Person.find_by(id: person_id)

transaction = Neo4j::ActiveBase.new_transaction

transaction.run do |tx|
  person.update(name: 'New name')
end

transaction.run do |tx|
  person.update(number: 1)
end

transaction.close

Причина, по которой эта функциональность желательна, заключается в том, что я использую Neo4jrb внутри Trailblazer-Operation. Первоначальная операция разбита на отдельные этапы, которые сами по себе записаны как отдельные методы. Я хочу, чтобы несколько шагов были заключены в транзакцию, но, без необходимости исправления операции, у меня нет возможности выполнить некоторые шаги внутри одного блока транзакции.

Спасибо!

1 ответ

Решение

Вот и получается, что у моей проблемы есть несколько решений.

Хотя мне сразу не было очевидно, что это так, после создания новой транзакции в Neo4jrb любые последующие запросы в этом же сеансе автоматически ассоциируются с транзакцией, пока она остается открытой.

person = Person.find_by(id: person_id)

transaction = Neo4j::ActiveBase.new_transaction

one = person.update(name: 'New name')

two = person.update(number: 1)

transaction.close

В приведенном выше примере оба one а также two совершены как часть transaction, Так что это решает мою проблему.

Другое решение моей проблемы, это то, что trailblazer-operation имеет особый метод для упаковки шагов в блок транзакции БД, как описано на веб-сайте Trailblazer.

step Wrap ->(*, &block) { Sequel.transaction do block.call end } {
  step Model( Song, :new )
  step Contract::Build( constant: MyContract )
  step Contract::Validate( )
  step Contract::Persist( method: :sync )
}

В приведенном выше примере все step методы внутри step Wrap называются в рамках Sequel.transaction блок.

Другие вопросы по тегам