jfinal的嵌套事务

莫莫水心 发布于 2013/09/27 09:23
阅读 841
收藏 0

@JFinal 你好,想跟你请教个问题:关于jfinal的嵌套事务,我参考你在oschina上的回答,自己写了一个MyDb,用于调用内部事务,外部仍然用Db,但是测试发现虽然走了commit,但是却没有提交,全部回滚了,请问下怎么回事呢,我的代码哪写错了?

public class MyDb {


public  static boolean tx(IAtom atom) {
Connection conn = null;

Boolean autoCommit = null;
try {
conn = DbKit.getDataSource().getConnection();
autoCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
boolean result = atom.run();
if (result)
conn.commit();
else
conn.rollback();
return result;
} catch (Exception e) {
if (conn != null)
try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
return false; // throw new ActiveRecordException(e);
} finally {
try {
if (conn != null) {
if (autoCommit != null)
conn.setAutoCommit(autoCommit);
conn.close();
}
} catch (Exception e) {
e.printStackTrace(); // can not throw exception here, otherwise the more important exception in previous catch block can not be thrown
}
}
}
}

加载中
1
JFinal
JFinal
    添加 try catch 块,在catch 块中用  Db.method(DbKit.getDataSource(), ...) 来保存数据到库中,不会被回滚,然后在此 catch 块中再抛出异常,让外部事务可以被回滚
0
pandyyan
pandyyan
你参考的JFinal哪个版本?你这么写肯定不支持嵌套事务的conn = DbKit.getDataSource().getConnection(); 这是获取一个新的连接,不是当前线程连接,嵌套事务必须保证从始至终是一个conn的,你看下JFinal1.4的Db源码就知道了。
山东-小木
山东-小木
如何保证始终是一个conn 在不同数据源下切换的时候 conn肯定变 事务回滚只能自己写
0
pandyyan
pandyyan

JFinal目前已经支持嵌套事务了,不知道你扩展Db出于什么考虑?

一路找北
回复 @莫莫水心 : 考虑下先回滚了再记录异常,记录异常的DB操作不要和业务的操作放在一个事物里,不然一起回滚了
pandyyan
pandyyan
回复 @莫莫水心 : 不太明白你的需求,你是想记录异常日志后再回退?如果想记录log那也只能将log存入文本,也不可能存入到数据库吧!
莫莫水心
莫莫水心
@莫莫水心 对了,是最新的1.4
莫莫水心
莫莫水心
我是想整个出现异常了的时候,异常保存入库,其余的回退
0
莫莫水心
莫莫水心
@ pandyyan 我是想整个出现异常了的时候,异常保存入库,其余的回退
0
0
pandyyan
pandyyan
如果要记录异常日志,可以对增删改查加try..catch,然后再catch中记录日志,如果这么做了,catch中一定要throw ActiveRecordException(e),否则事务就不起作用了。
0
莫莫水心
莫莫水心

引用来自“pandyyan”的答案

如果要记录异常日志,可以对增删改查加try..catch,然后再catch中记录日志,如果这么做了,catch中一定要throw ActiveRecordException(e),否则事务就不起作用了。

我没有抛异常,我回去检查看看,我现在是这样写的,直接跳转500页面

try{

ai.invoke();
}catch(Exception e){
//取出当前操作人的userId,ip
Controller controller = ai.getController();
User user = (User) controller.getSession().getAttribute(Constants.LOGIN_USER);
String ip = IpHelper.getIpAddr(controller.getRequest());
Long userId = null;
if(user!=null){
userId = user.getLong("userid");
}
//此处需要起事务(方式有点复杂,淡定)
BusinessLogInsertAtom businessLogInsertAtom = new BusinessLogInsertAtom(e, userId, ip);
Db.tx(businessLogInsertAtom);


this.setDefault("/WEB-INF/front/common/_500.html");
pandyyan
pandyyan
你没必要自己在扩展Db类了,直接用就行。
返回顶部
顶部