Java修道之路:JFinal一坑,事务不回滚问题

其实就是被坑了一下,哪个猿不是从坑里爬出来的呢?有个朋友说过,“有什么坑的,就记下来,下次不要被坑了”,可是,我觉得真是“一朝若被坑,永生真●难忘”,根本不用记录,呵呵。

但,这篇文章不是想描述我如何被坑的,而是为了记录一个处理问题的过程!

使用公司自己的一个eclipse插件做开发,该插件集成了JFinal框架,也不知道是哪个版本的JFinal,不过可以肯定的是2.0以前的。

写了一段业务,删除A表指定记录 -> 插入A表一条记录 -> 批量插入B表n条记录 -> 批量插入C表n条记录(记录从D表中查出),下面是伪代码:

Db.tx(new IAtom() {

	@Override
	public boolean run() throws SQLException {

		try {
			Db.update("delete from A where id = ?", id);
			Db.update("insert into A values(null,?,?)", new Object[]{param1, param2});

			// 准备参数
			Object[][] objss1 = new Object[row][3];
			for (int i = 0; i < row; i ++) {
				objss[i][0] = param3;
				objss[i][1] = param4;
				objss[i][2] = param5;
			}
			Db.batch("insert into B values(null,?,?,?)", objss1, 1000);

			// 准备参数
			Object[][] objss2 = new Object[row][1];
			for (int i = 0; i < row; i ++) {
				objss[i][0] = param6;
			}
			Db.update("insert into C select * from D where id = ?", objss2);

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
});

上述代码中,我是通过显示声明事务,即通过Db.tx(iatom)方法开启事务,照理如果在操作数据库的任何一个环节出错,所有的操作都应该回滚。

正好我在写代码的过程中,从D表中查数据时的sql写错了,这时就报错了,但是我发现,前面的所有操作都没有回滚……..

这怎么可能,突然就慌了(这心理素质居然敢来撸代码,也是醉了),为什么会慌呢,可能是之前学习事务的时候在潜意识中留下的阴影(来来来,求阴影面积),用心理学的一个术语来说,就叫做“习得性无助”(来,跟我读,“习得性‘ 无助”,那个谁,谁叫你读成“习得’ 性无助”的,我们研究心理学,你倒好,研究起啪啪啪学了,给我站起来重新读500遍),什么叫做习得性无助呢,简单解释就是遇到一个问题受阻,慢慢的由应激反射变成了条件反射,最终对问题产生了恐惧心理… 扯远了,其实就是我对解决事务问题有恐惧,潜意识认为就是无解的,呵呵,这个问题就值得研究了,看来是个心理问题!!!

这时,自然是求助场外观众了,一个同事告诉我,我们的mysql事务级别是Read Commited,也就是说只能看到提交后的数据,那么可以对每一步数据库操作进行断点,然后查看数据库,哪一步能看到断点的操作,那么问题就出现在这一步,因为Db.tx还没有执行完,事务是不会提交的,但是能看数据操作,说明这一步的事务已经提交,那么就是问题所在!

我就这么一步一步的操作,最终终于找到问题位置,问题处在Db.batch(…)方法,也就是批量操作的方法,为什么呢,赶紧上网搜索Db.batch的事务问题,果不其然,找到了詹总回复的一个问题:

JFinal2.0之前的某个版本批量操作Db.batch事务问题

“Db.batch中的事务与其他jfinal api中的事务是独立的,所以不能将他们的事务统一成一个事务”!!!看完后,只想说,坑坑更健康…… 然后,就把所有的Db.batch全部改成了Db.update…(不过后面版本已经将batch方法纳入到事务中了,我试过2.2是没有问题的)。

其实,被坑是在所难免的事,关键是查错方法:一步一步的找出问题源,只要找到了问题源,那么就好办了。对于其他错误我都是这么找问题源来处理的,可是一看到事务的问题,就什么都给忘了…呵呵,以后就记住了,被坑多了,方法自然也就熟络了!

本文《Java修道之路:JFinal一坑,事务不回滚问题》来自 www.juwends.com ,欢迎转载或CV操作,但请注明出处,谢谢!