@Transactional在JPA和Hibernate中有什么用?

时间:2019-01-23 11:33:14

标签: java hibernate spring-boot jpa

我正在学习如何使用JPA和Hibernate和MySQL数据库创建REST API,并且看到了@Transactional注释。有人可以解释此注释的用途吗?

例如,我有一个简单的DAO类:

@Repository
public class EmployeeDAOHibernateImpl implements EmployeeDAO {

    // define field for entitymanager
    private EntityManager entityManager;

    // set up constructor injection
    @Autowired
    public EmployeeDAOHibernateImpl(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    @Transactional
    public List<Employee> findAll() {

        // get the current hibernate session
        Session currentSession = entityManager.unwrap(Session.class);

        // create a query
        Query<Employee> theQuery = 
                currentSession.createQuery("from Employee", Employee.class);

        // execute query and get result list
        List<Employee> employees = theQuery.getResultList();

        // return the results
        return employees;
    }

}

您可以看到用于findAll()方法的@Transactional,但是如果删除此@Transactional,则会得到相同的输出...那么,此@Transactional的用途是什么?

4 个答案:

答案 0 :(得分:4)

通常@Transactional注释是在服务级别编写的。

它用于通过单个原子操作组合数据库中的多个写入

当有人调用用@Transactional注释的方法时,对数据库的全部写入或不执行执行

对于读操作,它没有用,因此在单个原子写的情况下也是如此。您正在单次读取(选择)中使用它,因此添加或删除@Transactional批注没有影响。

答案 1 :(得分:2)

如果要在事务中执行某些方法/类(=内部的所有方法),请使用

@Transactional批注。

假设用户A希望将100 $转移给用户B。会发生什么:

  1. 我们将A的帐户减少了100 $
  2. 我们将100美元添加到B的帐户中

我们假设在成功1)之后和执行2)之前引发了异常。现在我们会有某种不一致的地方,因为A损失了100美元,而B一无所获。 交易意味着全部或全部。如果方法中某处引发异常,则更改不会保留在数据库中。发生rollback之类的事情。

如果您未指定@Transactional,则每个数据库调用将处于不同的事务中。

答案 2 :(得分:0)

要大致熟悉@Transactional注释,请查看this文章。要深入研究,请参阅春季docs

答案 3 :(得分:0)

该类在其自身或其成员上声明@Transactional,Spring创建一个代理,该代理实现与您要注释的类相同的接口。换句话说, Spring在代理中包装了bean,而bean本身对此一无所知

代理为Spring提供了一种在方法调用之前,之后或周围将行为注入到被代理对象中的方式。

在内部,它与使用事务通知(使用AOP)相同,先创建代理,然后在目标bean的方法之前/之后调用代理。

生成的代理对象提供了TransactionInterceptor,该对象由Spring创建。因此,当从客户端代码调用@Transactional方法时,TransactionInterceptor首先从代理对象被调用,该代理对象开始事务并最终在目标bean上调用该方法。调用完成后,TransactionInterceptor相应地提交/回滚事务