- 首页|
- linux|
- ruby|
- ROR|
- 敏捷开发|
- 扯|
- 桌面show|
- Ajax on rails|
- design pattern|
- The Ruby Way |
- railscast|
- 技巧|
- mac|
- mysql|
- 粒计算|
- 数工|
- flex on rails
热门文章
搜索BLOG文章
最新评论
- [匿名]admin:什么玩艺?
- [匿名]lynn1221:每一种数据库系统都有优点和缺点,..
- [匿名]sfsa:垃圾检测
- [匿名]aoner:这问题2.3.8都还没解决,用了你的方..
- fsjoy1983:废话,你在.git外部一层目录执行能..
51CTO推荐博文
更多>>
rails实现“事务”的方法
原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://fsjoy.blog.51cto.com/318484/96738
在学习数据库时,曾经提到事务,最典型的一个实例就是银行转账的问题。
A帐户向B帐户转账100块,这个事情一定要发生两件事情,A的帐户上减去100块,B的账户上加上100块。如果半路发生问题而中断这个事情,那么必须回滚到初始状态。
下面来看一下用rails来实现这个例子:
首先,建立模型类account, 数据迁移:
在account类中定义方法:
实施数据迁移。运行console
>> peter = Account.create(:balance=>100, :number=>"12345")
>> paul = Account.create(:balance=>200, :number=>"54321")
#create直接创建并保存到accounts表中
现在数据库中的内容#SELECT * FROM account_development.account
继续在console里运行:
>> Account.transaction do
?> paul.deposit(10)
>> peter.withdraw(10)
>> end
此时数据库中的内容:
现在再来看看异常情况,1.从peter帐户上转350出去给peter
>> Account.transaction do
?> paul.deposit(350)
>> peter.withdraw(350)
>> end
------
这时抛出了异常:
ActiveRecord::RecordInvalid: Validation failed: Balance is negative!
---数据库还是保持原样:
2.从peter账户上转10出去给tom
>> Account.transaction do
?> paul.deposit(10)
>> tom.withdraw(10)
>> end
----抛出异常:
NameError: undefined local variable or method `tom' for #<Object:0x389a0>
数据库依然保持原样。
虽然数据库依然保持原样,但是模型对象会发生变化,look:
现在还是恢复原状,peter有100块,paul有200块
现在执行:
结果出乎意料,
Transfer aborted!
Paul has 550.0
peter has -250.0
模型对象已经被改变了!
原因就在于ActiveRecord并没有跟踪对象在事务前后的状态,实际上它也跟踪不了, 因为没有一种简单的办法可以知道哪些模型对象参与了事务。为了解决这个问题,我们可以把涉及一次事务的模型对象以参数的形式明确的告诉transaction
这次结果就跟我们料想的一样了:
T
A帐户向B帐户转账100块,这个事情一定要发生两件事情,A的帐户上减去100块,B的账户上加上100块。如果半路发生问题而中断这个事情,那么必须回滚到初始状态。
下面来看一下用rails来实现这个例子:
首先,建立模型类account, 数据迁移:
在account类中定义方法:
实施数据迁移。运行console
>> peter = Account.create(:balance=>100, :number=>"12345")
>> paul = Account.create(:balance=>200, :number=>"54321")
#create直接创建并保存到accounts表中
现在数据库中的内容#SELECT * FROM account_development.account
继续在console里运行:
>> Account.transaction do
?> paul.deposit(10)
>> peter.withdraw(10)
>> end
此时数据库中的内容:
现在再来看看异常情况,1.从peter帐户上转350出去给peter
>> Account.transaction do
?> paul.deposit(350)
>> peter.withdraw(350)
>> end
------
这时抛出了异常:
ActiveRecord::RecordInvalid: Validation failed: Balance is negative!
---数据库还是保持原样:
2.从peter账户上转10出去给tom
>> Account.transaction do
?> paul.deposit(10)
>> tom.withdraw(10)
>> end
----抛出异常:
NameError: undefined local variable or method `tom' for #<Object:0x389a0>
数据库依然保持原样。
虽然数据库依然保持原样,但是模型对象会发生变化,look:
现在还是恢复原状,peter有100块,paul有200块
现在执行:
结果出乎意料,
Transfer aborted!
Paul has 550.0
peter has -250.0
模型对象已经被改变了!
原因就在于ActiveRecord并没有跟踪对象在事务前后的状态,实际上它也跟踪不了, 因为没有一种简单的办法可以知道哪些模型对象参与了事务。为了解决这个问题,我们可以把涉及一次事务的模型对象以参数的形式明确的告诉transaction
这次结果就跟我们料想的一样了:
T