有时候配置了注解@Transactional,可是它会失效,这里要注意一些细节问题,以免落入陷阱。
注解@Transaction的底层实现是Spring AOP技术,而Spring AOP技术使用的是动态代理。这就意味着对于静态(static)方法和非public方法,注解@Transactional是失效的。还有一个更为隐秘的,并且在使用过程当中极其容易犯错误的——自调用。
所谓自调用,就是一个类的一个方法去调用自身另一个方法的过程。数据库
出现这个的问题根本缘由在于AOP的实现原理。因为@Transactional的实现原理是AOP,而AOP的实现原理是动态代理,而本身调用本身的过程,并不存在代理对象的调用,这样就不会产生AOP去为咱们设置@Transactional配置的参数,这样就出现了自调用注解失效的问题。
为了克服这个问题,一方面可使用两个服务类,Spring IoC容器中为你生成了RoleService的代理对象,这样就可使用AOP,且不会出现自调用的问题。另一方面,你也能够直接从容器中获取Service的代理对象,从IoC容器中获取RoleService代理对象。可是有一个弊端,就是从容器获取代理对象的方法有侵入之嫌,你的类须要依赖于Spring IoC容器性能
数据事务是企业应用关注的核心内容,也是开发者最容易犯错的问题,所以笔者在这里讲解一些使用不良习惯,注意它们能够避免一些错误和性能的丢失。代理
互联网每每采用模型—视图—控制器(Model View Con-troller,MVC)来搭建开发环境,所以在Controller中使用Service是十分常见的。
在Controller每调用一次带事务的service都会建立数据库事务。若是屡次调用,则不在同一个事务中,这会形成不一样时提交和回滚不一致的问题。每个Java EE开发者都要注意这类问题,以免一些没必要要的错误。对象
在企业的生产系统中,数据库事务资源是最宝贵的资源之一,使用了数据库事务以后,要及时释放数据库事务。换言之,咱们应该尽量地使用数据库事务资源去完成所需工做,可是在一些工做中须要使用到文件、对外链接等操做,而这些操做每每会占用较长时间,针对这些,若是开发者不注意细节,就很容易出现系统宕机的问题。
一些系统之间的通讯及一些可能须要花费较长时间的操做,都要注意这个问题,放在controller层等事务外进行处理,以免长时间占用数据库事务,致使系统性能的低下。事务
带事务的service中,出现异常想要回滚时应抛出异常,而不是捕获资源