当前位置:首页 > 面试题 > 正文内容

同一个类中无事务方法a()内部调用有事务方法b()的问题

关中浪子3年前 (2021-07-26)面试题1123
【腾讯云】2核2G4M云服务器新老同享99元/年,续费同价
找梯子最重要的就是稳定,这个已经上线三年了,一直稳定没有被封过,赶紧下载备用吧!


1. 事务的4种特性        

序号    参数    含义
1    原子性(Atomicity)    事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。
2    一致性(Consistemcy)    事务前后,数据库的状态都满足所有的完整性约束。
3    隔离性(Isolation)    并发执行的事务是隔离的,一个不影响一个。通过设置数据库的隔离级别,可以达到不同的隔离效果
4    持久性(Durability)    在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
2.Transactional()控制事务传播的配置项目(默认Propagation.REQUIRED)

    @Transactional(propagation=Propagation.REQUIRED)           //控制事务传播。默认是Propagation.REQUIRED
    @Transactional(isolation=Isolation.DEFAULT)                //控制事务隔离级别。默认跟数据库的隔离级别相同
    @Transactional(readOnly=false)                             //控制事务可读写、只可读。默认可读写
    @Transactional(timeout=30)                                 //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同
    @Transactional(rollbackFor=RuntimeException.class)         //控制事务遇到哪些异常会回滚。默认是RuntimeException
    @Transactional(rollbackForClassName=RuntimeException)      //同上
    @Transactional(noRollbackFor=NullPointerException.class)   //控制事务遇到哪些异常不会回滚。默认遇到RuntimeException回滚
    @Transactional(noRollbackForClassName=NullPointerException)//同上
3.事务的7中传播特性4. 事务的传播案例:

序号    传播行为    含义
1    REQUIRED    如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
2    SUPPORTS    如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
3    MANDATORY    如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4    NESTED    如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行
5    NEVER    总是非事务地执行,如果存在一个活动事务,则抛出异常
6    REQUIRES_NEW    总是开启一个新的事务。如果一个事务已经存在,则将这个已经存在的事务挂起
7    NOT_SUPPORTED    总是非事务地执行,并挂起任何存在的事务
4.举个上手的按例:事务在A类的a()方法中调用B类的b()方法的传播案例

 

A.a()    B.b()的事务配置    a()没有事务的结果    a()有事务的结果
REQUIRED    b()创建自己的事务;    b()接受a()的事务
SUPPORTS    b()不创建自己的事务;    b()接受a()的事务
MANDATORY    b()报异常    b()接受a()的事务
NESTED    b()创建自己的事务;    b()接受a()的事务,成为a()嵌套的子事务
NEVER    b()不创建自己的事务;    b()报异常
REQUIRES_NEW    b()创建自己的事务;    b()不接受a()的事务,b()先执行,内层事务失败不会影响外层事务
NOT_SUPPORTED    b()不创建自己的事务;    b()不接受a()的事务,b()先执行
Java案例:

public class PropagationTest extends BaseServerTest {
 
    private static final Logger logger = Logger.getLogger(PropagationTest.class);
 
 
    @Test
    @Transactional()
    public void a() {
        try {
            PropagationTestB classb = new PropagationTestB();
            classb.b();
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}
 
 
class PropagationTestB {
 
    @Autowired
    TRSMapper trsMapper;
 
    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, rollbackFor = RuntimeException.class)
    public void b() {
        try {
            trsMapper.saveNews(new JSONArray());
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}

5.特殊案例分析:

Java案例:无事务a()方法中调用同一个类的有事务b()方法问题案例

public class PropagationTest extends BaseServerTest {
 
    private static final Logger logger = Logger.getLogger(PropagationTest.class);
 
    @Autowired
    TRSMapper trsMapper;
 
    @Test
    public void a() {
        try {
            b();
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
 
    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, rollbackFor = RuntimeException.class)
    public void b() {
        try {
            trsMapper.saveNews(new JSONArray());
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}

声明式事务基于Spring AOP实现,将具体业务逻辑与事务处理解耦,在 Spring 的 AOP 代理下,只有目标方法由外部调用,目标方法才由 Spring 生成的代理对象来管理,这会造成自调用问题。

即:

同一类中a()方法没有@Transactional 注解,在其内部调用有@Transactional 注解的方法,有@Transactional 注解的方法b()的事务被忽略,不会发生回滚。


扫描二维码推送至手机访问。

版权声明:本文由码农翻生发布,如需转载请注明出处。

本文链接:https://lubojian.cn/post/36.html

分享给朋友:

相关文章

spring的4种事务特性,5种隔离级别,7种传播行为

spring的4种事务特性,5种隔离级别,7种传播行为

spring事务:什么是事务:事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. 事务特性(4种):原子性 (atomicity):强调事务的不可分割.一致性 (consistency):事务的执行的前...

2023 java 基础面试题

Q1:Java内部类和子类之间有什么区别?答案:内部类是指在一个外部类的内部再定义一个类,内部类对外部类有访问权限,可以访问类中定义的所有变量和方法。子类是从父类(superclass)中继承的类,子类可以访问父类所有public和prot...

JAVA面试题附答案(长期更新)

JAVA基础基本类型分为数值型(byte,short,int,long,float,double),字符型,布尔型引用类型包含类,接口,数组String能被继承吗?为什么?不可以,因为String类有final修饰符,而final修饰的类是...

Java笔试题大全带答案,2023年精选解答

1. 下面关于java.lang.Exception类的说法正确的是()A 继承自Throwable B Serialable CD 不记得,反正不正确答案:A解析:Java异常的基类为java.lang.Throwable,java.la...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。