如何在Spring Data中使用@Transactional?

时间:2012-05-01 07:33:58

标签: java spring jpa spring-data spring-data-jpa

我刚刚开始研究Spring-data,Hibernate,MySQL,JPA项目。我切换到spring-data,这样我就不用担心手工创建查询了。

我注意到当你使用spring-data时不需要使用@Transactional因为我在没有注释的情况下尝试了我的查询。

我应该/不应该使用@Transactional注释的具体原因是什么?

使用:

@Transactional
public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

也有效:

public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

提前致谢!

4 个答案:

答案 0 :(得分:114)

你的问题实际上是什么?使用@Repository注释或@Transactional

完全不需要

@Repository,因为您声明的接口将由Spring Data基础架构创建的代理支持,并且无论如何都会激活异常转换。因此,在Spring Data存储库接口上使用此注释根本没有任何效果。

@Transactional - 对于JPA模块,我们在支持代理(SimpleJpaRepository)的实现类上有这个注释。这有两个原因:首先,持久化和删除对象需要JPA中的事务。因此,我们需要确保一个事务正在运行,我们通过使用@Transactional注释该方法来完成。

findAll()findOne(…)之类的阅读方法正在使用@Transactional(readOnly = true),这不是绝对必要的,但会在事务基础结构中触发一些优化(将FlushMode设置为{{1}在关闭MANUAL时让持久性提供程序可能跳过脏检查。除此之外,该标志也在JDBC连接上设置,这导致该级别的进一步优化。

根据您使用的数据库,它可以省略表锁,甚至拒绝您可能意外触发的写操作。因此,我们建议您使用EntityManager作为查询方法,您可以轻松地将该注释添加到存储库接口。确保在您可能已在该界面中声明或重新修饰的操作方法中添加普通@Transactional(readOnly = true)

答案 1 :(得分:3)

我认为这个问题有点宽泛,无法减少数据访问层的注释。我们需要考虑应用程序的整个堆栈,我们想要应用的事务策略等等。 Mark Richards在IBM developerworks网站上有一篇关于此主题的非常全面的文章。你可以在这里找到第一个:http://www.ibm.com/developerworks/java/library/j-ts1/index.html

最好的问候

答案 2 :(得分:2)

您应该使用@Repository注释

这是因为@Repository用于将未经检查的SQL异常转换为Spring Excpetion,唯一应该处理的异常是DataAccessException

答案 3 :(得分:0)

我们还使用@Transactional批注来锁定记录,以便其他线程/请求不会更改读取。