2

YAML ファイルに格納されている SQL ステートメント (更新、挿入、および削除) を実行するクラスがあります。すべてのステートメントを 1 つのトランザクションの一部にしたいと考えています。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 呼び出しを 1 つのトランザクションの一部にしたいと考えています。dm-transactions gem のコードを見てきましたが、このコンテキストでの使用方法がわかりません。

4

3 に答える 3

5

これを使用して、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

RubyDataMapperおよびdm-transactions_spec.rbでのトランザクションの使用をご覧ください。

于 2011-09-16T13:05:50.190 に答える
4

私が知る限り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 を使用してから 1 年になります) によると、DataMapper トランザクションの動作は AR の動作を模倣しています。

于 2012-04-25T01:41:59.340 に答える
0

原則として、応答はまだ正しいです。User.transactionは、モデル「User」が接続されているリポジトリ(データベース)でトランザクションを開きます。より一般的な方法は

DataMapper.repository(:default).transaction do |t|
    t.commit
end
于 2011-09-16T13:21:34.460 に答える