在Spring Boot中整合Shiro来引入权限管理功能,可是在对数据库表进行增删改操作时发现,事务注解@Transactional不起作用,Spring无法托管事务。导致每个操作语句都会被自动提交——这是不应该被允许的!
实际上在一开始,并不清楚这是因为Shiro导致的问题,因此在网上寻找答案时都使用“Spring事务注解失效”来做关键词,并且找到了一大堆不相干的答案,但是其中有许多问题反复出现,在此统一罗列出来以作警醒。
一、当发现Spring事务注解不起作用的时候可能的原因
1、Spring的事务注解@Transactional只能放在public修饰的方法上,如果在private、protected方法上虽然不报错,但是事务不起作用
2、如果采用Spring+Spring MVC应用,则context:component-scan重复扫描问题可能会引起事务失败
3、如果使用Mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,需要改成InnoDB引擎
4、Spring Boot启动类上没有添加@EnableTransactionManagement 开启注解配置——但是实际上,新版Spring Boot已经不需要这个配置了,因为底层已经自动开启了注解配置
5、Spring团队建议在具体的类(或类的方法)上使用@Transactional注解,而不要使用在类所要实现的任何接口上。在接口上使用@Transactional注解,只能当你设置了基于接口的代理时它才生效。因为注解是不能继承的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装
6、在业务代码中如果抛出RuntimeException异常;但是抛出Exception,事务不会滚(这点存疑,不知道是不是真的)
7、如果在加有事务的方法内,使用了try……catch……语句块对异常进行了捕获,而catch语句块中没有throw new RuntimeException异常,事务也不会回滚
8、在类A里面有方法a和方法b,然后方法b上面用@Transactional加了方法级别的事务,在方法a里面调用了方法b,方法b里面的事务不会生效,原因是在同一个类中,方法互相调用,贴面无效,而不仅仅是事务。这里事务之所以无效,是因为Spring的事务是通过AOP实现的
二、关于整合Shiro使得Spring Boot的事务注解失效的原因
这次的问题出现在整合Shiro时配置的自定义组件Realm——用于进行授权和认证管理的组件。其中调用了Service层的组件,并且因此导致问题的出现。
在这里通过注入Service层组件时添加一个注解:@Lazy
就可以解决啦!

具体原因分析:时间久远,当时忘记写分析了,现在也忘记了原因,在此暂且按下不表,以后有机会再接触到Shiro的时候再看吧




