论坛首页 编程语言技术论坛

Rails的transaction

浏览 14311 次
精华帖 (7) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-01-07   最后修改:2011-01-19
    今天同事问我关于rails transaction,如果有多个不同表回滚,如何做。我告诉他,就嵌套着写多个transaction,而且十分坚定的告诉他:只写一个是绝对绝对不行的!我以前遇到过,多表回滚的问题,后来就是这样解决的!
    同事表示怀疑,去看api,告诉我,我错了,我当时怒了,不可能吧!
    经过讨论,又看完api,一起做了一个小测试,证明我确实错了。
    很久以前,其实我也不是很明白多表回滚如何实现,记得当时写过一个多表保存,要求有回滚。发现数据更新时有问题,找不到原因。我以为是多表回滚失败导致的,后来看了下面的帖子。http://www.iteye.com/problems/18595google,搜索“rails,多表事务”,第一页第一个就是(JE的SEO做的还是不错的)。当时照着这个方法,加上嵌套的transaction,修改后,测试没问题。所以对此法深信不疑。其实当时的的错误并没有修改,而是没有测试到。
    关于rails的多表回滚,只要写一个就可以。api解释如下http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
引用
Different Active Record classes in a single transaction
Though the transaction class method is called on some Active Record class, the objects within the transaction block need not all be instances of that class. This is because transactions are per-database connection, not per-model.

In this example a balance record is transactionally saved even though transaction is called on the Account class:

  Account.transaction do
    balance.save!
    account.save!
  end
The transaction method is also available as a model instance method. For example, you can also do this:

  balance.transaction do
    balance.save!
    account.save!
  end

   
    现在,大家知道了这个问题的回答是错误的,但是无论是作者还是回答者都无法对问题进行修改。JE的SEO做的不错,我不清楚有多少人会通过google第一页,搜索rails,多表事务来找到这个问答,又有多少人会会被这个帖子误导。
    众多人都表示压力很大。只要采纳或者过期就无法编辑。
    趁这个机会对问答版块提点建议:
    1,对问题答案采纳后也能够进行编辑。
    2,最好能够向stackoverflow等网址借鉴些经验,所有用户都可以对问题答案进行一个简单投票,这样大家在看问题回答的时候,可以有重点的查看。并且能够对最终的结果进行一个汇总和编辑,虽然采纳了某个人的答案,但是并不意味这最终的答案是属于这个人的,应该是集思广义,对最后的结果进行一个编辑汇总,这样的结果才是一个最佳的结果。
    3,我一直不明白为什么提问题还要积分?用完积分不是就不能提了么?提的问题好应该给加分,但是同时如果这个问题没有任何意义,google一搜一堆结果,同样可以投反对票。
    大家有什么好的建议可以一起提出来。我帮忙汇总下。
   发表时间:2011-01-08  
我错了……想改过来都不行了
0 请登录后投票
   发表时间:2011-01-09  
用了也不会错,只要你的数据库事务的传播级别设为PROPAGATION_REQUIRED,嵌套子事务会用最上面的那个transaction。
这个一般是默认值。
0 请登录后投票
   发表时间:2011-01-09  
JE的问答板块是挺奇怪的,只要采纳了或者过期的问题都不能编辑了,少了很多进一步交流的机会啊。
0 请登录后投票
   发表时间:2011-01-10   最后修改:2011-01-10
自己写的一个 事务管理器 原理用的 观察者模式(其实一个List也可以搞定)
依靠JDK自带的观察者模式完成
/**
 * 事务观察者
 * @author CC
 */
public class TransactionObserver implements Observer {
	
	private Connection conn = null;

	public void update(Observable obs, Object obj) {
		try {
			if ("C".equals(obj)) {
				if(conn != null){
					conn.commit();
				}
			} else if ("R".equals(obj)) {
				if(conn != null){
					conn.rollback();
				}
			} 
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void setConnection(Connection connObj) {
		this.conn = connObj;
	}
}

/**
 * 被观察的事务
 * @author CC
 */
public class TransactionObservable extends Observable {
	
	public void commit(){
		this.setChanged();
		this.notifyObservers("C");
	}
	
	public void rollback(){
		this.setChanged();
		this.notifyObservers("R");
	}
}




//设置数据库连接对象事务
private TransactionObservable ooServer = null;
TransactionObserver oo = new TransactionObserver();
Connection conn = XXXXXXXX;
conn.setAutoCommit(false);// true or false
oo.setConnection(conn);
this.ooServer.addObserver(oo);

//调用
try{
//自己加一个begin事务方法(也就是设置conn.setAutoCommit(false);// true or false)

//XXX_1数据库操作

//XXX_2数据库操作

//XXX_3数据库操作

ooServer.commit();
}catch(Exception e){
ooServer.rollback();
}
0 请登录后投票
   发表时间:2011-01-10  
ywbanm 写道
JE的问答板块是挺奇怪的,只要采纳了或者过期的问题都不能编辑了,少了很多进一步交流的机会啊。



我觉得也不方便。

je  改一下 咯
0 请登录后投票
   发表时间:2011-01-11  
说实话je的用户体验太差了

1.登录后只跳转到首页;
2.验证用户是否登录用客户端验证
3.浏览帖子的页面没有发表新帖的链接
0 请登录后投票
   发表时间:2011-01-11  
问答做的烂就不说了。有目共睹。
还有其它
不登录就没有收藏链接,登录后就跳转到首页了,找不到我要收藏的文章在哪里。
0 请登录后投票
   发表时间:2011-01-11   最后修改:2011-01-11
baiyuxiong 写道
问答做的烂就不说了。有目共睹。
还有其它
不登录就没有收藏链接,登录后就跳转到首页了,找不到我要收藏的文章在哪里。


这里好像没人要挽留你啊.你去做个不烂的吧。
0 请登录后投票
   发表时间:2011-01-11  
dsjt 写道
说实话je的用户体验太差了

1.登录后只跳转到首页;
2.验证用户是否登录用客户端验证
3.浏览帖子的页面没有发表新帖的链接


太差你又跑来这里干什么呢?犯贱?去些体验好的地方吧。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics