spring中@transactional注解的测试

注解的定义

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
   ...
}

根据元注解的定义,事务注解可以定义在类、接口、枚举、方法上 ,在日常的开发中一般写到service层(约定
在这里插入图片描述

常见问题分析

  • 在springboot项目中放在controller层是否起作用?
    答案是:起作用。(但是约定不能这么做
    下方例子中:保存点A不报错,保存点B处报错,保存点A数据回滚(数据回滚,因为发生了运行时异常,rollbackFor默认回滚运行时异常或非受检异常,还有error级别异常)
 /**
     * controller层进行事务测试
     */
    @RequestMapping("/tran")
    //rollbackFor = {Exception.class} 此处其实不起作用,发生了运行时异常
    @Transactional(rollbackFor = {Exception.class}) 
    public void testTransaction(){
        Dlzd dlzd = new Dlzd();
        dlzd.setDlbh("99");
        dlzd.setDlmc("test");
        dlzdService.save(dlzd);  // 保存点A
        Dgd dgd = new Dgd();
        dgd.setDdh("1111");
        dgdService.save(dgd);// 保存点B
    }
  • @transactional 只有在public修饰的方法上起作用,protected,private不起作用?
    答案是:正确的
    下方例子中:保存点A不报错,保存点B处报错,保存点A数据不回滚,数据保存到了数据库中,证明注解不起作用

 /**
     * controller层进行事务测试
     */
    @RequestMapping("/tran")
    @Transactional(rollbackFor = {Exception.class})
    protected void testTransaction(){
        Dlzd dlzd = new Dlzd();
        dlzd.setDlbh("99");
        dlzd.setDlmc("test");
        dlzdService.save(dlzd);  // 保存点A
        Dgd dgd = new Dgd();
        dgd.setDdh("1111");
        dgdService.save(dgd);// 保存点B
    }
  • @transactional 为什么建议加上rollbackfor = Exception.class?
    答案是:注解默认回滚的是unchecked exception非受检的异常 ,runtimeException。受检的Exception,不进行事务的回滚,顾要加上
    下方例子中:保存点A不报错,保存点B处报错,保存点A数据不回滚(没有加rollbackFor
@RequestMapping("/test3")
    @Transactional
    public void testTransaction3() throws Exception{
        Dlzd dlzd = new Dlzd();
        dlzd.setDlbh("99");
        dlzd.setDlmc("test");
        dlzdService.save(dlzd); //保存点A

        Dgd dgd = null;
        try {
            dgd = new Dgd();
            dgd.setDdh("1111");
            dgdService.save(dgd); //保存点B
        } catch (Exception e) {
            e.printStackTrace();
            throw  new Exception("test");
        }

    }

此处一开始测试时,使用了lombok的@SneakyThrows注解,数据照样回滚(原因是lombok捕获异常后抛出的仍然为runtimeException,故照样回滚)

@RequestMapping("/test3")
    @Transactional
    @SnekyThrows
    public void testTransaction3(){
        Dlzd dlzd = new Dlzd();
        dlzd.setDlbh("99");
        dlzd.setDlmc("test");
        dlzdService.save(dlzd); //保存点A

        Dgd dgd = null;
        try {
            dgd = new Dgd();
            dgd.setDdh("1111");
            dgdService.save(dgd); //保存点B
        } catch (Exception e) {
            e.printStackTrace();
            throw  new Exception("test");
        }

    }

@SnekyThrows
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值