异常和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; |