如何在 Ruby DataMapper 中使用事务?

发布于 2024-12-05 03:01:20 字数 715 浏览 2 评论 0原文

我有一个执行存储在 YAML 文件中的 SQL 语句(更新、插入和删除)的类。我希望所有报表都成为一笔交易的一部分。如果任何 SQL 语句失败,那么它们将被回滚。如果所有声明都成功,那么它们将被提交。我正在连接到 MySQL 数据库。这是我的代码:

require 'dm-core'

class SqlExecuter

  def initialize(input_yaml_file_name)
    @input_yaml_file_name = input_yaml_file_name
    @adapter = DataMapper.repository(:default).adapter
    @sql_statements = YAML::load(File.open(input_yaml_file_name))
  end

  def execute()
    puts "Executing SQL statements in #{@input_yaml_file_name} file...."

    @sql_statements.each do | sql_statement |
      @adapter.execute(sql_statement)
    end
  end
end # class SqlExecuter

我想让所有 @adapter.execute 调用成为一个事务的一部分。我查看了 dm-transactions gem 中的代码,但我不知道如何在这种情况下使用它。

I have a class that executes SQL statements (updates, inserts, and deletes) that are stored in a YAML file. I would like all the statements to be part of one transaction. If any of the SQL statements fail, then they would be rolled back. If all of the statements are successful, then they would be committed. I'm connecting to a MySQL database. Here is my code:

require 'dm-core'

class SqlExecuter

  def initialize(input_yaml_file_name)
    @input_yaml_file_name = input_yaml_file_name
    @adapter = DataMapper.repository(:default).adapter
    @sql_statements = YAML::load(File.open(input_yaml_file_name))
  end

  def execute()
    puts "Executing SQL statements in #{@input_yaml_file_name} file...."

    @sql_statements.each do | sql_statement |
      @adapter.execute(sql_statement)
    end
  end
end # class SqlExecuter

I'd like to have all of my @adapter.execute calls be part of one transaction. I've looked at the code in the dm-transactions gem, but I can't figure out how to use it in this context.

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

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

发布评论

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

评论(3

明天过后 2024-12-12 03:01:20

使用它来在事务中体现您的 SQL 语句,并在发生错误时回滚:

require 'dm-transactions'
YourModel.transaction do |t|
  begin
    @sql_statements.each do |sql_statement|
      DataMapper.repository(:default).adapter.execute(sql_statement)
    end
  rescue DataObjects::Error
    t.rollback
  end
end

看看 通过 Ruby DataMapper 使用事务dm-transactions_spec.rb

Use this to embody your SQL statements in a transaction and rollback if an error occurs:

require 'dm-transactions'
YourModel.transaction do |t|
  begin
    @sql_statements.each do |sql_statement|
      DataMapper.repository(:default).adapter.execute(sql_statement)
    end
  rescue DataObjects::Error
    t.rollback
  end
end

Take a look at Using transactions with Ruby DataMapper and dm-transactions_spec.rb

苏辞 2024-12-12 03:01:20

据我所知,您不再需要调用 rollback() 来回滚事务。您只需将其包含在事务块中,如下所示:

YourModel.transaction do
  @sql_statements.each do |sql_statement|
    DataMapper.repository(:default).adapter.execute(sql_statement)
  end
end

至少,这就是我阅读 关于回滚的 dm-transactions 规范

it 'should rollback when an error is raised in a transaction' do
  @user_model.all.size.should == 0
  lambda {
    @user_model.transaction do
      @user_model.create(:name => 'carllerche')
      raise 'I love coffee'
    end
  }.should raise_error('I love coffee')
  @user_model.all.size.should == 0
end

我一直在使用 DataMapper 编写一个相当大的应用程序,其中包含大量事务,但没有使用rollback(),并且我所有失败的事务总是回滚。

另外,根据我对 ActiveRecord 的记忆(我已经使用 AR 一年了),DataMapper 事务行为模仿了 AR 行为。

As far as I can tell, you no longer need to call rollback() for a transaction to be rolled back. You merely need to enclose it in a transaction block, like so:

YourModel.transaction do
  @sql_statements.each do |sql_statement|
    DataMapper.repository(:default).adapter.execute(sql_statement)
  end
end

At least, that's how I read the dm-transactions spec about rollbacks:

it 'should rollback when an error is raised in a transaction' do
  @user_model.all.size.should == 0
  lambda {
    @user_model.transaction do
      @user_model.create(:name => 'carllerche')
      raise 'I love coffee'
    end
  }.should raise_error('I love coffee')
  @user_model.all.size.should == 0
end

I've been writing a sizable application using DataMapper with plenty of transactions and without the use of rollback(), and all of my failed transactions always rollback.

Also, from what I remember about ActiveRecord (it's been a year since I've used AR), the DataMapper transaction behavior mimics the AR behavior.

吲‖鸣 2024-12-12 03:01:20

原则上,这个反应还是正确的。 User.transaction 将在模型“User”附加到的存储库(数据库)上打开一个事务。更通用的方法是

DataMapper.repository(:default).transaction do |t|
    t.commit
end

Im principle, the response is still correct. User.transaction will open a transaction on the repository (database) that the model "User" is attached to. A more generic way is

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