如何使用 ruby​​ mysql2 执行事务

发布于 2025-01-05 05:51:16 字数 460 浏览 1 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

以酷 2025-01-12 05:51:16

我刚刚完成了一个实现:

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

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
飞烟轻若梦 2025-01-12 05:51:16

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

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')
倾其所爱 2025-01-12 05:51:16

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

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
萌面超妹 2025-01-12 05:51:16

我刚刚使用

klass.transaction 做
....
结尾
其中 Klass 是我插入的 ActiveRecord 类

I just used

klass.transaction do
....
end
where Klass is the ActiveRecord class that Im inserting to

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文