首先数据库建两张表,如下图所示,用于测试事务是否进行回滚。
(1)正常操作,action路径命名为saveEm,将id值传入25进行保存。成功保存。
controller
@Inject
LoginService loginService;
public void saveEm(){
int id = getParaToInt("id");
try {
News news = getModel(News.class);
news.setId(id);
Notice notice = getModel(Notice.class);
notice.setId(id);
loginService.ss(news);
loginService.yy(notice);
} catch (Exception e) {
e.printStackTrace();
}
service
package com.legendnet.exam.login;
import com.legendnet.model.News;
import com.legendnet.model.Notice;
public class LoginService {
public boolean ss(News news) throws Exception{
return news.save();
}
public boolean yy(Notice notice) throws Exception{
return notice.save();
}
}
(2)将id值传入24,对于表一来说会出现主键冲突所以会抛出异常,经过测试我们发现事务并没有进行回滚。
(3)接下来我们将拦截规则设置为 me.addGlobalServiceInterceptor(new TxByMethodRegex("(.*save.*|.*update.*)"));针对service层进行拦截。经过测试,我们发现依旧没有发生回滚,改造service层如下:
public boolean save(News news,Notice notice) throws Exception{
news.save();
notice.save();
return true;
}
改为这样后,我们发现事务进行回滚了。通时测试service层不抛异常,发现事务也进行回滚了。
总结:通过以上示例可以看出,一个action中如果想进行事务处理则必须将后续操作放在同一个service中。jfinal升级到3.5之后,配置了controller 和interceptor层可通过@Inject注解,将service层进行注入。因此建议在开发中编写service层。在service层中进行事务处理。在controller中进行异常捕获即可。
注:如果经过上述测试仍发现事务未进行回滚。请记住jfinal事务是建立在数据表引擎INNODB的基础上。