-
关于Rails中多表保存的事务一致性5
关于Rails中多表操作的事务一致性
User has_one UserDetail 一个用户有一个用户明细,里面保存了用户的详细信息
User has_many MarkDetails 一个用户有多个积分明细,里面记录了每次获得积分的记录
Message 站内信
应用场景:
用户通过认证后,要更新一下users表中的是否通过验证的标志字段,同时更新一下用户明细表中的一些
信息,另外通过身份认证后,用户将得到100的积分,还要给用户发送一个站内认告诉他这件事情。
class User < ActiveRecord::Base def confirmed_width_auth(id_card) self.is_auth = 1 self.user_detail.id_card = id_card mark_detail = self.mark_details.new mark_detail.mark = 100 mark_detail.description = "身份认证得到积分" message = Message.new message.subject = "身份认证,得到积分" message.body = "你得到100积分" message.to_id = self.id # 很明显,上面涉及到要保存三张表的信息,我应该接下来怎么处理 来保证事务的一致性呢? self.save && mark_detail.save && message.save # 我这样做行不? # 另外好像在关联的表,在Rails中是可以进行事务处理的,而没有关联的表好像不能进行事务处理的,是这样的吗? end end
在那个<应用Rails进行敏捷开发>的书上有讲到Rails中active record中的事务处理,不过那例子讲到的是在同一个表中不同的记录间所执行的操作,对于多个不同的表(甚至是没有任何关联的表),我们应该怎么来安全的处理事务呢?
因为我做的是一个电子商务方面的应用,所以对于业务操作中的事务还是非常关注的,我希望能正确的安全的完成整个业务 方法的执行。
请有验证的和有想法的大大们指点一下,谢谢。
问题补充:
谢谢nt,引用1.捕捉异常。
2.数据库回滚,对象不回滚。(千万要记住)
关于1是应该在controller中进行么?
关于2你想说什么?能具体 一点吗?
问题补充:transaction do self.save! mark_detail.save! message.save! end
我自己试了一下,以上的代码能正确工作,你为什么不用这样的代码呢?
比你刚才那圆环套圆环的方法好看一些啊。
我还是对 Rails的ar的事务处理机制不100%明白
问题补充:
我自己测试过的,数据库中相关表中的记录的事务能保证的,你可以试试,
不过你所说的
非 User 对象应该无法回滚
是指user的实例 对象无法回滚到先前的状态吗?2009年6月11日 11:13
5个答案 按时间排序 按投票排序
-
采纳的答案
这个 transaction do ... end 其实是调用了 Uer 的类方法。
而 User.transaction 只控制 user 表的回滚, 别的表它不管的。
这个三环可以简化一下(最后一环其实没用到):User.transaction do MarkDetails.transaction do self.save! # 不过这一步可能连带保存了 mark_detail ? # 如果只生成一条 sql,就是单连接的事务,可以回滚 …… mark_detail.save! message.save! end end
你用transaction do self.save! mark_detail.save! message.save! raise 'error' end
试试看是不是都回滚了……
参考 http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
引用
A transaction acts on a single database connection. If you have multiple class-specific databases, the transaction will not protect interaction among them. One workaround is to begin a transaction on each class whose models you alter:
transaction 是连接相关的,如果能保证只在一个数据库连接中做所有事情,应该一个套就够了,但是不一定保险 ……
2009年6月11日 18:23
-
在 controller 和 model 都可以。如果不打算提供过于具体的出错信息,甚至可以写个处理异常的 filter,一次搞定。
第二条,考虑这个情况:
第一步保存了 user,第二步保存 mark_detail 出错,那么第一步保存的 user 记录会回滚消失。但这个回滚是数据库做的,回滚了什么东西 rails 不知道,所以 user 对象还是刚 save 时的状态,甚至还有一个子虚乌有的 id 属性…… 要继续使用这个对象,得注意这点。2009年6月11日 17:11
-
更正: MarkDetails --> MarkDetail
还有一点设计上的: 这个东西涉及到多个类,万一 User 膨胀到很大很大(我说的是万一……),分离出 Service 类好点。2009年6月11日 16:40
-
User.transaction do
MarkDetails.transaction do
Message.transaction do
self.save!
mark_detail.save!
message.save!
end
end
end
save! 是异常版,如果其中出了异常,三张表都回滚。
另外要注意的:
1.捕捉异常。
2.数据库回滚,对象不回滚。(千万要记住)2009年6月11日 16:37
相关推荐
NULL 博文链接:https://dendrobium.iteye.com/blog/305938
Ruby on Rails中文指南
NULL 博文链接:https://hlee.iteye.com/blog/591526
Ruby On Rails中文教材(PDF)
rails指南 中文版
敏捷Rails中文教程 敏捷Rails中文教程 敏捷Rails中文教程
NULL 博文链接:https://wikimo.iteye.com/blog/622212
使用Aptana+Rails开发Rails Web应用 有Aptana的安装配置等等,中文
NULL 博文链接:https://hlee.iteye.com/blog/1236898
rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails ...
rails-assets, 在 Rails 中,资产管理的解决 Rails 资产 Bundler 到 Bower 代理本自述文件涉及项目的开发方面。 访问站点了解如何在你的应用程序中使用 Rails 资产。 插件开发设置git clone git@github.com:tenex/r
Advanced Rails,英文版,一本关于Rails的好书!
在过去的几年中,《Ruby on Rails Tutorial》这本书被视为介绍使用 Rails 进行 Web 开发的先驱者。 在这个全球互联的世界中,计算机编程和 Web 应用程序开发都在迅猛发展,我很期待能为中国的开发者提供 Ruby on ...
可实现多文件的同时上传,控制文件的格式,数量,同时兼容IE6,7,firefox,易于扩展
《Rails之道》详细讨论了Rails的程序代码并通过分析Rails中的代码片段来深入解释它的功能,同时,《Rails之道》部分章节也摘录了一些API文档中的内容,使读者能够快速地找到对应的API文档、相关的示例代码以及深入...
中文世界唯一一本Rails 4.0.0 + Ruby 2.0.0 的自學書籍
Rails Guides 5.0 中文版
本资源是参照rails敏捷开发第四版书中的例子,rails的版本是rails3.2.6
这是关于rails 2.0 API文档,方便查询,是热爱rails人员的必备武器