我刚刚开始研究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);
}
提前致谢!
答案 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批注来锁定记录,以便其他线程/请求不会更改读取。