Spring @Transactional 到底是怎么工作的?

在这篇文章中,我们将会深入分析spring 事务管理机制,我们将看到@Transactional是如何工作的。

JPA和事务管理

注意到JPA自己并不提供任何类型的声明的事务管理是很重要的。当在一个依赖注入容器中的外部使用JPA时,事务需要由开发者手动管理
UserTransaction utx = entityManager.getTransaction(); 
    try { 
        utx.begin(); 
        businessLogic();
        utx.commit(); 
    } catch(Exception ex) { 
        utx.rollback(); 
        throw ex; 
    }

管理事务的方式使得事务的作用范围一目了然,但是有几个缺点
1、重复性很高并且已发生错误
2、任何错误都可能会导致很严重的影响
3、错误很难调试和复制
4、会降低代码的可读性
5、如果这个方法调用了另一个事务方法了怎么办?

使用spring的@Transactional

使用spring的@Transactional的时候,上边的代码就会简化成下边的形式:
  @Transactional
    public void businessLogic() {
        ... use entity manager inside a transaction ...
    }

这更方便也具有可读性,这也是在spring中推荐的方式。 通过使用 @Transactional,很多重要的方面比如事务传播被自动处理,在这种情况下,如果另外一个事务方法被这个事务方法调用了,那个方法将会有选择的的进入这个运行的事务中去。潜在的问题是,强大而又复杂的机制在标签下运行,一旦出现问题就会导致很难调试。

@Transactional是什么意思

@Transactional的两个关键点是有两个不同的概念需要了解,每一个都有自己的范围和生命周期
the persistence context
the database transaction
这个事务标签自己定义了一个单一数据库事务的范围,数据库事务的范围在持久化的上下文范围内。JPA中的持久化上下文时EntityManager,内部实现了Hibernate的Session(当使用Hibernate作为持久层的提供者)。持久化上下文仅仅是一个同步对象,它跟踪了有限个java对象并确保在这些对象上的改变最终都会持久到数据库中去。这和数据库事务的任何一个概念都有很大的区别,一个Entity Manager可以在很多个数据库事务中被使用,实际上也是的。

什么时候EntityManager跨度多个数据库事务

最常见的例子是当应用程序在View模式中使用OpenSession,在这样的例子中,在view层的查询,被分成多个数据库事务,但是他们是通过一个entity manager 完成的。另一个例子是,当持久化的上下文被开发者标记为PersistenceContextType.EXTENDED的时候,意味着它可以在多个请求中存活。

什么定义了EntityManager VS 事务关系

这其实是开发者的一个选项,但是最常见的方式采用一个应用事务使用一个Entity Manager的模式,注入EntityManager最常见的方式是:
@PersistenceContext
    private EntityManager em;

这里我们默认是 一个应用事务使用一个Entity Manager的模式,在这种模式下,如果我们在@Transactional方法中使用这个EntityManager,那么这个方法将会在一个单独的数据库事务中运行。


原文地址:http://blog.jhades.org/how-does-spring-transactional-really-work/

你可能感兴趣的:(spring,事务,事务)