我有一个类,它执行存储在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中的代码,但我无法弄清楚如何在这种情况下使用它。
答案 0 :(得分: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
查看Using transactions with Ruby DataMapper和dm-transactions_spec.rb
答案 1 :(得分:4)
据我所知,您不再需要调用rollback()
来回滚事务。您只需要将它包含在事务块中,如下所示:
YourModel.transaction do
@sql_statements.each do |sql_statement|
DataMapper.repository(:default).adapter.execute(sql_statement)
end
end
至少,这就是我阅读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
我一直在使用DataMapper编写一个相当大的应用程序,并且没有使用rollback()
,并且所有失败的事务都会回滚。
此外,根据我对ActiveRecord的记忆(自从我使用AR以来已经过去一年),DataMapper事务行为模仿了AR行为。
答案 2 :(得分:0)
我的原则,反应仍然正确。 User.transaction将在模型“User”附加到的存储库(数据库)上打开一个事务。更通用的方法是
DataMapper.repository(:default).transaction do |t|
t.commit
end