java 异常 & Transactional注解

记录日常设计遇到的java异常问题

一 结论/规律

1.非public 或者函数里包含了非public的函数情况 是不会回滚的

不会报错 也没有日志 需要特别注意

2.报的异常和rollBackFor的不同也不会回滚(rollback中异常至少是父类 或者同一类)

3.如果报异常 有数据库存储和查询动作 能查询到和且落库后回滚 如果id自增 会看到有id断层的情况

private void test(){
        xxxrepo.save(C);//存储C类
        xxxrepo.select(C);//能查到
        thow new Exception("异常");
}

如果id是自增的情况 会遇到这种情况

id name
1 A
2 B
4 D

4.如果在新建一个线程 子线程的异常 父线程是捕捉不到的

(这里可以看一下Future类,一种异步方式 )

5.同一个注解中使用了两个数据源或涉及其他系统交互 事务会失效

5.cglib代理方式可能会使得没有@inherted注解的类获取不到注解

transcational是有@inherted注解的

6.A类中B方法加了事务注解 C没有事务注解 但调用了B方法 在外部调用C的时候 没有事务

spring AOP造成的

二 spring做了什么

Transaction注解的可配置项

Transactional代码段

可选项:

  • transcationManager
    事务管理器
    jdbc里的是DateSource TransactionManager
    spring提供了PlatFormTranscationManager接口 供接入实现
  • value
    和transcationManager 一个意思 相同的用法(如果两个配置不一样会报异常)
    这里可以看下AliasFor注解 注意 JDK原生获取注解模式会使这个注解失效
    详见:https://blog.csdn.net/weixin_43888891/article/details/126962698
  • propagation
    事务传播机制

REQUIRED:默认值,支持当前事务,如果没有事务会创建一个新的事务
SUPPORTS:支持当前事务,如果没有事务的话以非事务方式执行
MANDATORY:支持当前事务,如果没有事务抛出异常
REQUIRES_NEW:创建一个新的事务并挂起当前事务
NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则将当前事务挂起
NEVER:以非事务方式进行,如果存在事务则抛出异常
NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与REQUIRED类似的操作
原文链接:https://blog.csdn.net/szy350/article/details/122466050
https://blog.csdn.net/szy350/article/details/122466050

  • isolation
    隔离级别 和DB一样的事务隔离级别
  • timeout
    事务超时时间
  • readonly
    事务是否只读 为的是防止两次select查询的不一样 我理解是对DB做一个snapshot操作
  • rollbackFor
    遇到哪些异常需要回滚
  • rollbackForClassName
    遇到哪些异常需要回滚 填写内容为class名称 (全称还是简称?)
  • noRollbackFor
    遇到哪些异常不需要回滚
  • noRollbackForClassName
    遇到哪些异常不需要回滚 填写内容为class名称

与数据库关系 与隔离级别关系

三 成熟框架对于异常的处理 (代码参考)

可供看源代码的类

  • 两下shift 搜 TransactionManager 继承spring的PlatFormTranscationManager
  • TransactionInterceptor
  • TransactionAspectSupport
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容