Java:为何事务的实际执行结果与预期不符

@Controller
@EnableAutoConfiguration
public class SampleController {


    @Autowired
    private WeiboRepository weiboRepository;

    @Autowired
    private TwitterRepository twitterRepository;

    @RequestMapping("/postWeibo")
    @ResponseBody
    public void postWeibo() {
        Weibo weibo = new Weibo("Weibo");
        weiboRepository.save(weibo);
        postTwitter();
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void postTwitter() {
        Twitter twitter = new Twitter("Twitter");
        twitterRepository.save(twitter);
        throw new RuntimeException();
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleController.class, args);
    }

}

代码逻辑:添加一条微博的同时添加一条推特,postTwitter手动抛出异常模拟回滚
预期结果:Twitter表由于抛出异常造成回滚,Weibo表正常添加
实际结果:虽抛出异常但Twitter、Weibo表均正常添加

请问我已经设置了@Transactional,事务级别为REQUIRED表明postTwitter会单独开启新的事务,为何实际执行结果与预期不符合呢?

public void postWeibo() {
        Weibo weibo = new Weibo("Weibo");
        weiboRepository.save(weibo);
        postTwitter();
}

代码中的postTwitter();相当于this.postTwitter();这样调用是不行的。参考https://blog.csdn.net/dapinxiaohuo/article/details/52092447。然后你把

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void postTwitter() {
        Twitter twitter = new Twitter("Twitter");
        twitterRepository.save(twitter);
        throw new RuntimeException();
    }

方法放到其他的service中,然后本service注入前面说的service,你再试试

1)spring推荐在具体类上使用@Transactional,而不是在接口上声明
2)@Transactional声明在类上,则对所有的public方法有效
3)使用了@Transactional的方法,被同一个类里面的未使用@Transactional的方法调用, @Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。

你的情况符合第三点,同一个类中没有声明事务的方法调用了声明事务的方法,事务无效

排除1 public 2 unchecked异常 3 数据库引擎要支持事务,
可能是Spring,Spring mvc两个配置文件扫描controller的问题:具体说来可能是这种情况,在applicationContext.xml里面开启了@transanction解释器,就会在applicationContext.xml配置的扫描包的时候把扫描到的@transanction这样的注解开启事务,然后Spring-mvc.xml也有扫描而且没有开启解释器就把,有事务功能的controller替换为没有事务功能的controller,@Transactional 就不起作用

查了一晚上找到了答案,上面的示例违反了链接中的第三条规则,即使用了@Transactional的方法,对同一个类里面的方法调用, @Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。

https://blog.csdn.net/gm37120...

背后的失效机制可以参考这两篇文章:

https://blog.csdn.net/seelye/...
https://blog.csdn.net/levae10...

https://blog.csdn.net/lqq3740/article/details/101673362 昨天刚写了这个问题的博客,希望能帮到楼主!

postWeibo 这个方法没有开启事务,postTwitter 这个方法开启事务了,所以你在postWeibo里面调用postTwitter 就不会引发回滚操作