# Upgrading to WaterDrop 2.8 **PLEASE MAKE SURE TO READ AND APPLY THEM!** ## Upgrading to WaterDrop 2.8 / `throw(:abort)` No Longer Allowed To Abort Transactions Replace: ```ruby producer.transaction do messages.each do |message| # Pipe all events producer.produce_async(topic: 'events', payload: message.raw_payload) end # And abort if no more events are needed throw(:abort) if KnowledgeBase.more_events_needed? end ``` With: ```ruby producer.transaction do messages.each do |message| # Pipe all events producer.produce_async(topic: 'events', payload: message.raw_payload) end # And abort if more events are no longer needed raise(WaterDrop::AbortTransaction) if KnowledgeBase.more_events_needed? end ``` ## Upgrading to WaterDrop 2.8 / `return`, `break` and `throw` Are No Longer Allowed Inside Transaction Block Previously, transactions would abort if you exited early using `return`, `break`, or `throw`. This could create unexpected behavior, where users might not notice the rollback or have different intentions. For example, the following would trigger a rollback: ```ruby MAX = 10 def process(messages) count = 0 producer.transaction do messages.each do |message| count += 1 producer.produce_async(topic: 'events', payload: message.raw_payload) # This would trigger a rollback. return if count >= MAX end end end ``` This is a source of errors, hence such exits are no longer allowed. You can implement similar flow control inside of your methods that are wrapped in a WaterDrop transaction: ```ruby MAX = 10 def process(messages) producer.transaction do # Early return from this method will not affect the transaction. # It will be committed insert_with_limit(messages) end end def insert_with_limit(messages) count = 0 messages.each do |message| count += 1 producer.produce_async(topic: 'events', payload: message.raw_payload) # This would trigger a rollback. return if count >= MAX end end ``` --- *Last modified: 2025-05-16 21:52:20*