Java for Web学习笔记(一零一):Spring框架中使用JPA(1)Transaction(上)
在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:
- org.springframework.orm.jpa.JpaTransactionManager,最标准和最常用的PlatformTransactionManager。管理的事务只用于一个持续化单元,只用于EntityManger的动作。这满足大部分的场景
- 如果使用多个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相关文章
上一篇: 毕业季,难忘校园搞笑情
推荐阅读
-
Java for Web学习笔记(一零一):Spring框架中使用JPA(1)Transaction(上)
-
Java for Web学习笔记(一零七):Spring框架中使用JPA(7)密码和BCrypt
-
Java for Web学习笔记(一零二):Spring框架中使用JPA(2)Transaction(下)
-
Java for Web学习笔记(一零三):Spring框架中使用JPA(3)JPA仓库
-
Java for Web学习笔记(一零六):Spring框架中使用JPA(6)Isolation和C3P0(下)
-
Java for Web学习笔记(一零五):Spring框架中使用JPA(5)Isolation和C3P0(上)