spring @Transactional的自调用失效问题与事务的典型错误用法剖析(Failure of self calling in spring @ transactional and analysis of typical wrong usage of transactions)

@Transactional的自调用失效问题  
  有时候配置了注解@Transactional,但是它会失效,这里要注意一些细节问题,以避免落入陷阱。
  注解@Transaction的底层实现是Spring AOP技术,而Spring AOP技术使用的是动态代理。这就意味着对于静态(static)方法和非public方法,注解@Transactional是失效的。还有一个更为隐秘的,而且在使用过程中极其容易犯错误的——自调用。
  所谓自调用,就是一个类的一个方法去调用自身另外一个方法的过程。

  出现这个的问题根本原因在于AOP的实现原理。由于@Transactional的实现原理是AOP,而AOP的实现原理是动态代理,而自己调用自己的过程,并不存在代理对象的调用,这样就不会产生AOP去为我们设置@Transactional配置的参数,这样就出现了自调用注解失效的问题。
  为了克服这个问题,一方面可以使用两个服务类,Spring IoC容器中为你生成了RoleService的代理对象,这样就可以使用AOP,且不会出现自调用的问题。另外一方面,你也可以直接从容器中获取Service的代理对象,从IoC容器中获取RoleService代理对象。但是有一个弊端,就是从容器获取代理对象的方法有侵入之嫌,你的类需要依赖于Spring IoC容器

典型错误用法的剖析
   数据事务是企业应用关注的核心内容,也是开发者最容易犯错的问题,因此笔者在这里讲解一些使用不良习惯,注意它们可以避免一些错误和性能的丢失。

错误使用Service
  互联网往往采用模型—视图—控制器(Model View Controller,MVC)来搭建开发环境,因此在Controller中使用Service是十分常见的。
  在Controller每调用一次带事务的service都会创建数据库事务。如果多次调用,则不在同一个事务中,这会造成不同时提交和回滚不一致的问题。每一个Java EE开发者都要注意这类问题,以避免一些不必要的错误。

过长时间占用事务
  在企业的生产系统中,数据库事务资源是最宝贵的资源之一,使用了数据库事务之后,要及时释放数据库事务。换言之,我们应该尽可能地使用数据库事务资源去完成所需工作,但是在一些工作中需要使用到文件、对外连接等操作,而这些操作往往会占用较长时间,针对这些,如果开发者不注意细节,就很容易出现系统宕机的问题。
  一些系统之间的通信及一些可能需要花费较长时间的操作,都要注意这个问题,放在controller层等事务外进行处理,以避免长时间占用数据库事务,导致系统性能的低下。

错误捕捉异常
  带事务的service中,出现异常想要回滚时应抛出异常,而不是捕获

转自:https://www.cnblogs.com/ooo0/p/11030130.html

————————

@Self calling invalidation of transactional
Sometimes the annotation @ transactional is configured, but it will fail. Here we should pay attention to some details to avoid falling into a trap.
The underlying implementation of annotation @ transaction is spring AOP technology, which uses dynamic proxy. This means that the annotation @ transactional is invalid for static and non-public methods. There is also a more secret one, which is very easy to make mistakes in the process of use – self invocation.
The so-called self invocation is a process in which a method of a class calls another method of its own.

The root cause of this problem lies in the implementation principle of AOP. Since the implementation principle of @ transactional is AOP, and the implementation principle of AOP is dynamic proxy, and there is no call of proxy object when calling its own process, AOP will not set the parameters configured by @ transactional for us, so there is the problem of invalidation of self call annotation.
In order to overcome this problem, on the one hand, two service classes can be used. The proxy object of roleservice is generated for you in the spring IOC container, so that AOP can be used without self invocation. On the other hand, you can also get the service proxy object directly from the container and the roleservice proxy object from the IOC container. However, one drawback is that the method of obtaining proxy objects from the container is suspected of intrusion. Your class needs to rely on the spring IOC container

Analysis of typical wrong usage
Data transaction is the core content of enterprise applications and the problem that developers are most likely to make mistakes. Therefore, the author explains some bad habits here and pays attention to them to avoid some errors and performance loss.

Wrong use of service
The Internet often uses model view controller (MVC) to build the development environment, so it is very common to use service in the controller.
Every time the controller calls a service with a transaction, a database transaction will be created. If it is called multiple times, it is not in the same transaction, which will cause inconsistent commit and rollback at the same time. Every Java EE developer should pay attention to such problems to avoid some unnecessary errors.

Long time consuming transactions
In the enterprise production system, database transaction resources are one of the most valuable resources. After using database transactions, database transactions should be released in time. In other words, we should use database transaction resources as much as possible to complete the required work, but in some work, we need to use file, external connection and other operations, which often take a long time. For these, if developers do not pay attention to details, it is easy to have the problem of system downtime.
The communication between some systems and some operations that may take a long time should pay attention to this problem and be processed outside the transactions such as the controller layer, so as to avoid occupying database transactions for a long time, resulting in low system performance.

Error catch exception
In a service with transactions, when an exception occurs and you want to roll back, you should throw an exception instead of catching it

转自:https://www.cnblogs.com/ooo0/p/11030130.html