异常和Error
异常主要分为两大类:
受检异常(Checked Exception):继承自
Exception类,但不继承自RuntimeException。编译器要求必须处理这些异常,通常通过
try-catch块或在方法签名中声明throws。示例:
IOException、SQLException、ClassNotFoundException等。未受检异常(Unchecked Exception):继承自
RuntimeException的类。编译器不要求必须处理这些异常,但可选择性地捕获。示例:
NullPointerException、ArrayIndexOutOfBoundsException、IllegalArgumentException等。
Error 类
Error是Throwable的一个子类,表示 JVM 所无法处理的严重问题,通常用于表示系统级别的错误。- 常见的
Error类型包括:OutOfMemoryError:当 JVM 无法分配内存时抛出。StackOverflowError:当线程的调用栈超过限制时抛出。InternalError:表示 JVM 内部发生了错误。
Spring的事务机制
Spring通过异常进行事务回滚的机制:
Spring 的默认事务机制,当出现
unchecked异常或Error时候回滚,checked异常的时候不会回滚;当有
try catch后捕获了异常,事务不会回滚,如果需要回滚, 要catch内throw new RuntimeException让事务回滚;
默认事务会在RuntimeException或Error的情况下回滚。
设置@Transactional(rollbackFor = Exception.class)时,所有的异常或Error都会回滚。
1 | import org.springframework.stereotype.Service; |
处理方式
在需要处理事务的地方添加上@Transactional注解
在 Spring 中,如果你使用 @Transactional 注解而不显式设置 rollbackFor 属性,
默认行为是:
只对运行时异常(RuntimeException)和错误(Error)进行回滚。
这意味着在事务方法中抛出任何子类为
RuntimeException的异常。例如
NullPointerException、IllegalArgumentException或DataIntegrityViolationException,将导致事务回滚。对于检查性异常(Checked Exception),如
IOException或者自定义的检查性异常,事务将不会回滚。除非你明确指定
rollbackFor属性来让这些异常导致回滚。
如果添加@Transactional(rollbackFor = Exception.class) 的情况下,所有异常都会回滚,如 IOException 或者自定义的检查性异常。
方式1
因为要保证当前方法具有返回值,在前端界面展示操作状态。
所以我们service层在添加了try catch日志打印后,抛出的runtime类异常需要在controller层进行捕获,捕获之后,在catch中编写操作失败后返回值的信息。
1 |
|
当然这样也可以,因为指定了回滚的是所有异常的父类,所以所有异常都会回滚。
1 |
|
方式2
在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常了
1 |
|
方式3
不依赖于Spring的异常捕获机制进行事务回滚,通过手动的session.rollback进行异常捕获后回滚事务也可。
这种方式太麻烦不推荐
1 | import org.hibernate.Session; |