Welcome 微信登录

首页 / 软件开发 / JAVA / Rails开发细节(四)Transactions事务

Rails开发细节(四)Transactions事务2013-12-11 51cto virusswb译事务在数据库应用开发中是相当重要的,尤其是在关系数据库中。典型的例子就是银行在转账,在两个账 户之间转账。

account1.deposite(100) account2.withdraw(100)
在ActiveRecord中使用transaction方法执行一段block来实现事务。在 block的最后,会提交事务,更新数据库,如果在block中发生异常,数据库会回滚所有改变。

Account.transaction doaccount1.deposite(100) account2.withdraw(100) end
下面是一个完整的例子,我们创建一个表格,有两个字段:账号和余额。

定义一个 Account类,包含deposit存钱和withdraw取钱两个方法。

create_table :accounts, :force => true do |t| t.string :number t.decimal :balance, :precision => 10, :scale => 2, :default => 0 end class Account < ActiveRecord::Base validate :price_must_be_at_least_a_cent def withdarw(amount) adjust_balance_and_save(-amount) end def deposit(amount) adjust_balance_and_save(amount) end def adjust_balance_and_save(amount) self.balance += amount save! end def price_must_be_at_least_a_cent errors.add(:balance, "is negative") if balance < 0 end end peter = Account.create(:balance => 100, :number => "12345") paul = Account.create(:balance => 200, :number => "23456") Account.transaction dopaul.deposit(10) peter.withdraw(10) end
我们可以通过

select * from accounts

查询一下数据,看看账户信息是否正确。

peter = Account.create(:balance => 100, :number => "12345")

paul = Account.create(:balance => 200, :number => "23456")

 

Account.transaction do

 paul.deposit(350)

 peter.withdraw(350)

end

再来试试异常的情况,再 来查查数据库,看看数据有没有回滚到初始值。

在异常的情况下,我们输出model对象的值看看。

puts "Paul has #{paul.balance}"puts "Peter has #{peter.balance}"
我们会发现虽然数据库没有破坏,但是model对象的值被修改 了。这是因为ActiveRecord没有跟踪对象的状态变化,事实上它也做不到。如果在你的应用中这是一个问题的 话,你可以求助于object_transactions插件。