Database has Transactions to bundle multiple things into a single operation to ensure Data Integrity and helps with Performance (timeout if something runs in Transaction for too long).
Active Record Transaction is the API to do all Transactions things of your database.
Implement a class that only enqueues a job after transaction is committed by overriding methods from ActiveRecord::ConnectionAdapters::TransactionState:
class AfterCommittedJob
attr :user_id, :args
def initialize(user_id, args)
@user_id = user_id
@args = args
end
def has_transaction_callbacks?
true
end
def trigger_transactional_callbacks?
true
end
def before_committed!(...)
# nothing to do here
end
def committed!(...)
Sidekiq::Client.push(
"class" => SomeJob,
"args" => *args
)
rescue => error
raise error.message
end
def rolledback!(...)
# nothing to do
end
end
record = AfterCommittedJob.new(123, { name: "juan" })
connection = ActiveRecord::Base.connection
if connection.transaction_open?
connection.current_transaction.add_record(AfterCommittedJob)
else
record.committed!
end