在ssh架构中,假设一个Controller注入并调用了一个Service,而Service上配置了声明性事务,代码如下:
@Service
@Transactional
public class NodeServiceImpl extends CommonServiceImpl
{
private static final Logger log = Logger.getLogger(NodeServiceImpl.class);
public void save(WfNodeEntity node)
{
node.setId("1");
try
{
this.save(node);
} catch (Exception e)
{
log.info("错误:这里发生异常了!" + e.getMessage());
e.printStackTrace();
}
}
}
我们故意让this.save(node)代码行发生错误(比如把(WfNodeEntity的@column故意改成一个不存在的字段),那么,会发生异常吗?log.info会记录下日志吗?答案是不会的。
因为我们采用的是hibernate,并且是声明性事务,因此,程序执行this.save(node)语句,只是把node放入了hibernate的缓存区域的一块持久化区域,并不会立即执行insert语句。因此程序不会发生异常,log.info()自然就不会执行。
这个save(WfNodeEntity node)方法完成后,返回到Controller层,事务才会被提交,此时hibernate才会刷新、清理缓存,开始执行insert语句,所以此时才会在Controller层抛出异常,并且从控制台是无法看到是save(WfNodeEntity node)方法的哪一行代码发生了异常。
如果想确切的记录this.save(node)这一行发生异常怎么办呢?很简单,在其后追加一行代码即可,即
try
{
this.save(node);
this.flush();
} catch (Exception e)
{
log.info("错误:这里发生异常了!" + e.getMessage());
e.printStackTrace();
}
这样由于进行了this.flush(),hibernate 会立即执行insert语句,并发生异常,然后被catch住,log.info就能准确记录下错误信息了。
网友评论