how do I perform transactions with ruby mysql2

天大地大妈咪最大 提交于 2020-01-01 11:46:34

问题


I've started using mysql2 gem. I'm trying to figure out a few basic things - one of them is how to explicitly perform transactions (for batch operations, like multiple INSERT/UPDATE queries).

In the old ruby-mysql, this was my approach:

client  = Mysql.real_connect(...)
inserts = [
  "INSERT INTO ...",
  "UPDATE .. WHERE id=..",
  # etc
]

client.autocommit(false)
inserts.each do |ins|  
  begin
    client.query(ins)
  rescue
    # handle errors or abort entirely
  end
end
client.commit

I couldn't find much in the docs - how can the same be done with mysql2?


回答1:


I just have done a implementation:

class DBConnector
  def transaction(&block)
    raise ArgumentError, "No block was given" unless block_given?
    begin
      client.query("BEGIN")
      yield
      client.query("COMMIT")
    rescue
      client.query("ROLLBACK")
    end
  end
end

So you could use like this:

DBConnector.transaction do
  # your db queries here
end



回答2:


This question made me curious, so I tracked down how Ruby on Rails handles transactions, and I found this code:

def begin_db_transaction
  execute "BEGIN"
rescue Exception
  # Transactions aren't supported
end

def commit_db_transaction #:nodoc:
  execute "COMMIT"
rescue Exception
  # Transactions aren't supported
end

def rollback_db_transaction #:nodoc:
  execute "ROLLBACK"
rescue Exception
  # Transactions aren't supported
end

Have you tried executing a begin and commit statement around your other statements?

client.query('begin')

inserts.each do |ins|  
  begin
    client.query(ins)
  rescue
    client.query('rollback')
    return
  end
end

client.query('commit')



回答3:


Using Bruno's template, then adding a transaction status indicator:

def transaction(&block)
    raise ArgumentError, "No block was given" unless block_given?
    begin
      raw_query("BEGIN")
      yield
      raw_query("COMMIT")
      return true # Successful Transaction
    rescue
      raw_query("ROLLBACK")
      return false # Failed Transaction
    end
end

Interacting with #transaction:

def run_queries(queries)
    raise ArgumentError, "Invalid Queries Argument: #{queries}" unless queries.respond_to?(:each)
    success = transaction do
        queries.each do |q|
            raw_query(q)
        end
    end
    raise RuntimeError, "Transaction Failed for Queries: #{queries}" unless success
end


来源:https://stackoverflow.com/questions/9288593/how-do-i-perform-transactions-with-ruby-mysql2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!