我正在学习如何使用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的用途是什么?
答案 0 :(得分:4)
通常@Transactional
注释是在服务级别编写的。
它用于通过单个原子操作组合数据库中的多个写入。
当有人调用用@Transactional
注释的方法时,对数据库的全部写入或不执行执行。
对于读操作,它没有用,因此在单个原子写的情况下也是如此。您正在单次读取(选择)中使用它,因此添加或删除@Transactional
批注没有影响。
答案 1 :(得分:2)
@Transactional
批注。
假设用户A
希望将100 $转移给用户B
。会发生什么:
我们假设在成功1)
之后和执行2)
之前引发了异常。现在我们会有某种不一致的地方,因为A
损失了100美元,而B
一无所获。
交易意味着全部或全部。如果方法中某处引发异常,则更改不会保留在数据库中。发生rollback
之类的事情。
如果您未指定@Transactional
,则每个数据库调用将处于不同的事务中。
答案 2 :(得分:0)
答案 3 :(得分:0)
该类在其自身或其成员上声明@Transactional
,Spring创建一个代理,该代理实现与您要注释的类相同的接口。换句话说, Spring在代理中包装了bean,而bean本身对此一无所知。
代理为Spring提供了一种在方法调用之前,之后或周围将行为注入到被代理对象中的方式。
在内部,它与使用事务通知(使用AOP)相同,先创建代理,然后在目标bean的方法之前/之后调用代理。
生成的代理对象提供了TransactionInterceptor
,该对象由Spring创建。因此,当从客户端代码调用@Transactional
方法时,TransactionInterceptor
首先从代理对象被调用,该代理对象开始事务并最终在目标bean上调用该方法。调用完成后,TransactionInterceptor
相应地提交/回滚事务