Java for Web学习笔记(一零一):Spring框架中使用JPA(1)Transaction(上)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/flowingflying/article/details/78937962

在spring中使用事务涉及的Bean

本学习将介绍一些在Spring中使用事务设计的Bean,有一个大致的概念认识,以便了解后面的代码。如果觉得枯燥,也可以在后面的学习中回过头来看。

  在之前的学习中,我们在每个方法中都要创建EntityManager,进行事务的开启、关闭、回滚,代码有些相当累赘。Spring的强项在于用标记来解决,标记为@org.springframework.transaction.annotation.Transactional或者@javax.transaction.Transactional,可以用于接口和类及其方法。

我们需要设置下面的bean来支持标记的使用

PlatformTransactionManager

  在Spring框架中,控制事务使用org.springframework.transaction.PlatformTransactionManager,我们在root上下文中定义它,这样就可以通过标记自动地进行事务的启动,commit、抛出RuntimeException时回滚等。Spring提供下面两个PlatformTransactionManager:

  1. org.springframework.orm.jpa.JpaTransactionManager,最标准和最常用的PlatformTransactionManager。管理的事务只用于一个持续化单元,只用于EntityManger的动作。这满足大部分的场景
  2. 如果使用多个persistence units或者事务跨多个类型的资源(例如包括EntityManager和Java Message Service资源),需要使用org.springframework.transaction.jta.JtaTransactionManager或其子类WebLogicJtaTransactionManager(用于webLogic服务器),WebSphereUowTransactionManager (WebSphere服务器)。JTA(Java Transaction API)提供者,因此对于非完全Java EE服务器(如tomcat)需要一个复杂的JTA配置,因此书建议如果使用多个数据源,不建议采用tomcat,而采用完全的J2EE服务器。

SharedEntityManagerBean

  在之前的学习中,我们先获取了EntityManager,然后再开启transaction。而spring框架则采用org.springframework.orm.jpa.support.SharedEntityManagerBean作为EntityManager的proxy,确保transaction使用唯一的EntityManager(entityManager在同一时刻,只被一个transaction所使用)在同一线程中运行,即thread-safe。注入这个EntityManager proxy的方式为:
@PersistenceContext //我们这里不使用@Inject,因为这是从proxy中获取的在同一事务内唯一的entityManager,而不是同一个entityManager实例。
EntityManager entityManager;

//我们还可以在使用不同的Entity Proxy,对应多个persistence context configurations
public class FooRepository{
    @PersistenceContext(unitName = "fooUnit")
    EntityManager entityManager;
    ...
}
public class BarRepository{
    @PersistenceContext(unitName = "barUnit")
    EntityManager entityManager;
    ...
}

异常归整:PersistenceExceptionTranslator

  在使用JDBC开发中,不同数据库厂家的SQLException扩展均不同,因此处理起来很麻烦。HAP定义了一个基于PersistenceException的异常,但仍忽略了很多(例如key重复),对于NoSQL而言,每个client library都有自己的异常,导致问题更为复杂。Spring框架及其相关的数据工具通过继承org.springframework.dao.DataAccessException解决这个问题,无论使用JDBC,Hibernate或其他O/RM,JPA,Java Data Object或者NoSQL。

  在root上下文中定义一个或者多个org.springframework.dao.support.PersistenceExceptionTranslator的实现,实现可以配置支持多种持续化技术。如果配置了多个实现,Spring将自动chains它们。

  org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean是翻译JPA异常的,包括底层的JDBC错误代码。

  当定义了PersistenceExceptionTranslator的实现,例如LocalContainerEntityManagerFactoryBean,的对于标记了@Repository,调用其方法所产生的异常将被翻译。注意和@Async一样,不能在类内部生效,只能对外部调用类方法时生效。


相关链接:我的Professional Java for Web Applications相关文章


阅读更多
换一批

没有更多推荐了,返回首页