非web环境下使用jfinal 关于数据库操作事物回滚问题

yy670010378 发布于 2015/11/03 11:24
阅读 370
收藏 0

@JFinal 你好,想跟你请教个问题:

用的jfinal 1.8版本 

数据库:


show engines; 



INSERT INTO `ENGINES` VALUES ('InnoDB', 'DEFAULT', 'Supports transactions, row-level locking, and foreign keys', 'YES', 'YES', 'YES'); 


下面程序

1.main方法里调用方法test1对modelTest1插入一条数据

2.test1方法里调用方法test2对modelTest2插入一条数据

抛出一个异常



@Before(Tx.class)

public static void main(String[] args)throws Exception {

  C3p0Plugin c3p0Plugin = new C3p0Plugin(“xxx”, "xxx", "xxx");
  c3p0Plugin.setDriverClass("xxx");
 c3p0Plugin.setInitialPoolSize(5);
 c3p0Plugin.setMaxPoolSize(5);
   c3p0Plugin.start();

        ActiveRecordPlugin mYarp = new ActiveRecordPlugin("mysql", c3p0Plugin);
        mYarp.setTransactionLevel(4);
        mYarp.setDialect(new MysqlDialect());
        mYarp.addMapping("test1", Test1.class);
        mYarp.addMapping("test2", Test2.class);
        mYarp.start();


test1();

}

@Before(Tx.class)

public static void test1()throws Exception{

boolean result = new Test1().set("name","test" ).save();

test2();

}


@Before(Tx.class)

public static void test2()throws Exception{

boolean result = new Test2().set("name","test" ).save();

 throw new Exception("11111");

}

发现抛出异常后,数据仍然存在没有被回滚

一时找不到原因哪里没设置好 不知道是不是非web环境原因 还是jfinal版本原因 可以帮忙看下?


加载中
0
JFinal
JFinal

   非 web 环境下并且是 jfinal 2.0 之前的版本,@Before(Tx.class) 拦截器不起作用,当然就不会回滚了,两个解决方案:

1:使用 Db.tx(...) 来做事务

2:使用 jfinal 2.0 版本的业务层事务,可使用拦截器,只需要 Duang.duang(YourService).justDoIt() 即可

     业务层拦截器的具体用法详见 jfinal 2.0 手册,在此下载:http://www.jfinal.com

yy670010378
yy670010378
回复 @JFinal : 詹总,可以帮忙看下下面的问题?二楼的评论
JFinal
JFinal
回复 @yy670010378 : duang 起来才是真的爽
yy670010378
yy670010378
感谢詹总 用第二种方法解决了
0
yy670010378
yy670010378

        C3p0Plugin a  = new C3p0Plugin("x", "x","x");
        a.setDriverClass("x");
        a.setInitialPoolSize(5);
        a.setMaxPoolSize(5);
        a.start();
        ActiveRecordPlugin aa = new ActiveRecordPlugin("a", a);
        aa.setTransactionLevel(4);
        aa.setDialect(new MysqlDialect());
        aa.addMapping("test1", Test1.class);
        aa.start();
        C3p0Plugin b  = new C3p0Plugin("x", "x","x");
        b.setDriverClass("x");
        b.setInitialPoolSize(5);
        b.setMaxPoolSize(5);
        b.start();
        ActiveRecordPlugin bb = new ActiveRecordPlugin("b", b);
        bb.setTransactionLevel(4);
        bb.setDialect(new MysqlDialect());
        bb.addMapping("test2", Test2.class);
        bb.start();
        Test3 service = Duang.duang(Test3.class);
        service.test();
a.stop();
aa.stop();
b.stop();
bb.stop();
@Before(Tx.class)
    public void test() throws Exception {
    new Test1().set("test1", "xx").save();
    new Test2().set("test2", "xx").save();

throw new Exception("11111111111");

}
发生异常时 只回滚了一个数据库操作 因为两个操作是关联 需要都回滚

网上搜到了您之前的回答

目前只能分别对每个数据源进行事务控制,多数据源处在同一事务中属于分布式事务的范畴,jfinal 未来会采用极简设计来实现,目前有实现方案,但不是极简,所以没有发布出来 (8个月前)  

多数据源的事务性,jfinal如何控制?

JFinal
JFinal
回复 @yy670010378 : 这样肯定还是解决不了问题,你可以再仔细琢磨一下。只要是涉及到多数据源处希望处于同一个事务中,就必定要用分布式事务的解决方案
yy670010378
yy670010378
恩 最后还是考虑先把两个数据源设置不自动提交 有问题都回滚 都没问题后 再提交
JFinal
JFinal
回复 @yy670010378 : 所以,我早就提醒过,这是分布式事务的范畴
yy670010378
yy670010378
回复 @JFinal :感谢詹总回答哈, 感觉两个数据源还是不能互相影响 第一种:先完成一个数据源的事 再完成第二个数据源的事 //如果问题出现在第二个数据源 第一个已经完成了 还可以回滚? 第二种是嵌套 感觉会发生和第一种一样的情况
JFinal
JFinal
还有一个不太严谨的办法,就是在外层用 Tx 拦截器搞定一个数据源的事务,在内层用 Db.tx(...) 搞定第二个数据源,切记在 Db.tx 内有异常需要再次抛出来,才能让 Tx 拦截器感知并回滚
下一页
返回顶部
顶部