事务在数据库应用开发中是相当重要的,尤其是在关系数据库中。典型的例子就是银行在转账,在两个账 户之间转账。
account1.deposite(100) account2.withdraw(100)
在ActiveRecord中使用transaction方法执行一段block来实现事务。在 block的最后,会提交事务,更新数据库,如果在block中发生异常,数据库会回滚所有改变。
Account.transaction do account1.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 do paul.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插件。
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据库
, number
, end
, transaction
account
rails 事务、rails save事务延迟、rails api开发、rails 微信开发、rails开发工具,以便于您获取更多的相关知识。