在事件处理时,很多操作是被绑定在一起的,如果其中一个执行出现错误,那么这一系列被绑定的操作,都将不能执行,对于之前已经执行的时间,我们需要对他进行回滚操作,将之前的操作撤回,这里主要用到Connection数据库管理类的回滚特性
void rollback()
- 回滚,意思就是数据库做修改之后未 commit 之前, 使用 rollback 可以恢复数据到修改之前
void rollback(Savepoint savepoint)
- 回滚到保存点,可以恢复数据到Savepoint的位置
这里列出回滚的方法
具体可参照:Connection类的简单使用_我叫BuGu的博客-CSDN博客_connection类
那么这里我们就需要了解到线程安全问题了,因为线程的执行是不可确定的那么在执行中,如何确保这个取回回滚的数据一定是这个线程独有的,也就是说,这个数据的操作会不会被其他线程操作,或者优先于其他线程操作,那这里我们就需要用到
ThreadLocal,也就是线程变量
ThreadLocal它给每个线程一个关联数据,这个数据是这个线程所独有的,不被共享,这个时候就可以保证回滚的独一性,也就不会发生线程安全的问题了
具体介绍可看:史上最全ThreadLocal 详解_FMcGee的博客-CSDN博客_threadlocal
但是对于一个项目来说,所处理的数据操作是海量的,这个时候如果我们对每个事件进行单独的编写回滚操作,相对而言成本过高
那么这个时候我们考虑使用过滤器,来统一处理这些回滚操作,这个时候就很简单了,一旦在提交事务获取事务这部分发生异常,被捕获后,直接进行回滚操作即可。
但是需要注意,这个异常必须能被过滤器捕获到,也就是说,一旦发生异常我们要在每一层进行捕获,并再次向上抛出异常,以达到让过滤器可以捕获到异常的目的。
public void deleteFile(String fid,File f) {
try {
delete(fid);
deleteFile(f);
}catch (Exception e){//发生异常被捕获
e.printStackTrace();
throw new RuntimeException("PhotoServiceImpl:delFile--异常");//向上抛出异常
}
}
注意一定要一直向上传
这里补充一个关于
try {
delete(fid);
deleteFile(f);
}catch (Exception e){//发生异常被捕获
e.printStackTrace();
throw new RuntimeException("PhotoServiceImpl:delFile--异常");//向上抛出异常
}finally {
return "界面"
}
如果这个时候发生异常且被捕获,但是上层并不会收到抛出的异常,也就导致,无法回滚,所以如果要向上抛出异常,就不能在finally中写上return语句,这样会覆盖抛出的异常,从而导致上层无法捕获到异常,回滚失败
本人刚刚开始学习JavaWeb的相关内容,如果有错欢迎,评论区告知