使用Springboot构建 mybatis+Shiro+Redis+Druid 的前后端分离web项目, 具体可以参考博客https://www.cnblogs.com/caichaoqi/p/8900677.html
在集成Shiro+Redis之后,发现数据库事物不起作用,即不论给Service方法加@Transactional,还是使用全局的事物AOP,在执行Service中的方法时都是没有事物的,可以通过下面代码来判断当前方法中是否有事物。
boolean actualTransactionActive = TransactionSynchronizationManager.isActualTransactionActive();
经过谷歌百度之后,发现了这个帖子https://stackoverflow.com/questions/21512791/spring-service-with-cacheable-methods-gets-initialized-without-cache-when-autowi,
发现在集成Shiro的时候,是需要自己实现 AuthorizingRealm的,而在该Realm中需要通过UserService中的方法来查询用户信息,所以就在该类中注入了UserService,这样就导致了该UserService在其他controller调用的时候,如果该UserService有事物,就会发现事物根本不起作用。
解决方法:
在自己实现的Realm中,在注入Service的时候,加上注解@Lazy 进行延时注入:
/**
* 自定义ShiroRealm 进行身份认证和授权
* @author Declan
*/
@Slf4j
public class MaccShiroRealm extends AuthorizingRealm {
@Autowired
@Lazy
private IUserService userService;
@Autowired
@Lazy
private IRoleService roleService;
@Autowired
@Lazy
private IPermissionService permissionService;
// ....
}