如何使用ruby mysql2执行事务

我已经开始使用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完成相同的操作?

我刚刚做了一个实现:

 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 

这个问题让我好奇,所以我追踪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 

您是否尝试围绕其他语句执行begincommit语句?

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

使用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