Can you manage transaction commit/rollback manually?
I'd 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'd like to transactionalise parts of that stream.
Whenever a "START" appears on the stream, a new transaction is begun. Whenever a "STOP" appears, the transaction is committed.
I'm struggling with the transactions.
I can see that I can do ActiveRecord::Base.transaction do ... end, but that won't work in this case unless I batch everything up, which isn't possible here because of the streams.
I saw that there's a transaction manager buried in ActiveRecord that I could potentially use (https://github.com/rails/rails/blob/0d76ab9c6f01e6390ba8878a296ff9d3ac6b9aa8/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb) but I haven't been able to get my tests passing against it.
I think part of the problem is also RSpec's transactional fixtures interfering, although disabling these didn't seem to solve the problem either.
Any help would be appreciated.
Thanks
I'd 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
to group the messages. The output of this is an array of pairs. If the first value of the pair is true, then the second value is the array of bodies, if not the bodies are just true false. With the data thus reorganised it is then trivial to use the existing transaction method.
you can manage transaction the following way
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
链接地址: http://www.djcxy.com/p/66234.html
上一篇: 用GDI +填充部分圆角矩形
下一篇: 你可以手动管理事务提交/回滚吗?