как мне выполнить транзакции с ruby ​​mysql2 - PullRequest
5 голосов
/ 15 февраля 2012

Я начал использовать камень mysql2. Я пытаюсь выяснить несколько основных вещей - одна из них заключается в том, как явно выполнять транзакции (для пакетных операций, таких как множественные запросы INSERT / UPDATE).

В старом ruby-mysql это был мой подход:

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

Я не смог найти много в документах - как это можно сделать с mysql2?

Ответы [ 3 ]

9 голосов
/ 25 мая 2012

Я только что сделал реализацию:

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

Так что вы можете использовать так:

DBConnector.transaction do
  # your db queries here
end
2 голосов
/ 15 февраля 2012

Этот вопрос вызвал у меня любопытство, поэтому я проследил, как Ruby on Rails обрабатывает транзакции, и обнаружил этот код :

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

Вы пытались выполнить begin иcommit заявление вокруг других ваших заявлений?

client.query('begin')

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

client.query('commit')
0 голосов
/ 21 июня 2013

Используя шаблон Бруно, затем добавив индикатор статуса транзакции:

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

Взаимодействие с #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
...