我已经开始使用mysql2
gem了。我试图找出一些基本的东西 - 其中之一是如何显式执行事务(对于批处理操作,如多个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
完成同样的工作?
答案 0 :(得分:9)
我刚刚完成了一项实施:
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
答案 1 :(得分:2)
这个问题让我很好奇,所以我追踪Ruby on Rails如何处理交易,我发现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
您是否尝试围绕其他声明执行begin
和commit
声明?
client.query('begin')
inserts.each do |ins|
begin
client.query(ins)
rescue
client.query('rollback')
return
end
end
client.query('commit')
答案 2 :(得分:0)
使用Bruno的模板,然后添加交易状态指示器:
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