Can you manage the commit / rollback transaction manually?
I would like to do something like this:
["START", "a", "b", "c", "STOP", "START", "d", "e", "STOP"].each do |message|
if message == "START"
Transaction.begin
elsif message == "STOP"
Transaction.commit if Transaction.active?
else
begin
Message.create!(body: message)
rescue
Transaction.rollback
end
end
end
In short, I have a stream of "messages" and I would like to process parts of that stream.
Whenever "START" appears in the thread, a new transaction starts. When "STOP" appears, the transaction is committed.
I am struggling with transactions.
I can see that I can do ActiveRecord :: Base.transaction do ... end, but in this case it won't work unless I load everything, which is not possible due to streams.
I saw that in the ActiveRecord similar transaction manager that I could use ( https://github.com/rails/rails/blob/0d76ab9c6f01e6390ba8878a296ff9d3ac6b9aa8/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb ), but I do not was able to skip my tests against it.
I think part of the problem is also related to the interference of RSpec transactions, although disabling them did not solve the problem either.
Any help would be appreciated.
thank
source to share
I would do this:
messages.chunk {|value| value != 'START' && value != 'STOP'}.each do |is_data, bodies|
if is_data
Message.transaction do
bodies.each {|body| Message.create(body: body)}
end
end
end
The first step is to use chunk
messages to group. This results in an array of pairs. If the first value of the pair is true, then the second value is an array of bodies, unless the bodies are true false. Thus, when reorganizing data, it is trivial to use the existing transaction method.
source to share
you can manage the transaction like this
manager = ActiveRecord::Base.connection.transaction_manager ... manager.begin_transaction ... manager.commit_transaction ... manager.rollback_transaction
or in your case
manager = ActiveRecord::Base.connection.transaction_manager
["START", "a", "b", "c", "STOP", "START", "d", "e", "STOP"].each do |message|
if message == "START"
manager.begin_transaction
elsif message == "STOP"
manager.commit_transaction
else
begin
Message.create!(body: message)
rescue
manager.rollback_transaction
end
end
end
source to share