您应该将@Transactional放在DAO类和/或它们的方法中,还是更好地注释使用DAO对象调用的服务类?或者对两个“层”都加注释有意义吗?
当前回答
@Transactional注释应该放在所有不可分割的操作周围。 使用@Transactional可以自动处理事务传播。在这种情况下,如果当前方法调用了另一个方法,那么该方法将可以选择加入正在进行的事务。
让我们举个例子:
我们有两个模型,即国家和城市。国家和城市模型的关系映射就像一个国家可以有多个城市,所以映射就像,
@OneToMany(fetch = FetchType.LAZY, mappedBy="country")
private Set<City> cities;
在这里国家映射到多个城市,获取他们懒惰。这里是@Transactinal的作用当我们从数据库中检索Country对象时,我们会得到Country对象的所有数据,但不会得到城市的集合,因为我们是懒洋洋地获取城市。
//Without @Transactional
public Country getCountry(){
Country country = countryRepository.getCountry();
//After getting Country Object connection between countryRepository and database is Closed
}
当我们想要从国家对象访问Set of Cities时,我们将在该Set中获得空值,因为只有该Set创建的对象没有初始化该Set的数据来获取Set的值,我们使用@Transactional,即,
//with @Transactional
@Transactional
public Country getCountry(){
Country country = countryRepository.getCountry();
//below when we initialize cities using object country so that directly communicate with database and retrieve all cities from database this happens just because of @Transactinal
Object object = country.getCities().size();
}
所以基本上@Transactional is Service可以在单个事务中进行多个调用,而无需关闭与端点的连接。
其他回答
理想情况下,服务层(管理器)表示业务逻辑,因此应该用@Transactional进行注释。服务层可以调用不同的DAO来执行DB操作。让我们假设在一个服务方法中有N个DAO操作。如果您的第一个DAO操作失败,其他DAO操作可能仍然通过,您将以不一致的DB状态结束。注释服务层可以避免这种情况。
服务层是添加@Transactional注释的最佳位置,因为这里呈现的大多数业务逻辑都包含细节级用例行为。
假设我们将它添加到DAO,从服务调用2个DAO类,一个失败,另一个成功,在这种情况下,如果@Transactional不在服务上,一个DB将提交,另一个DB将回滚。
因此,我的建议是明智地使用这个注释,只在服务层使用。
Github项目- java-algos
@Transactional应该用于服务层,因为它包含业务逻辑。DAO层通常只有数据库CRUD操作。
// the service class that we want to make transactional
@Transactional
public class DefaultFooService implements FooService {
Foo getFoo(String fooName);
Foo getFoo(String fooName, String barName);
void insertFoo(Foo foo);
void updateFoo(Foo foo);
}
春季文档:https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html
@Transactional注释应该放在所有不可分割的操作周围。 使用@Transactional可以自动处理事务传播。在这种情况下,如果当前方法调用了另一个方法,那么该方法将可以选择加入正在进行的事务。
让我们举个例子:
我们有两个模型,即国家和城市。国家和城市模型的关系映射就像一个国家可以有多个城市,所以映射就像,
@OneToMany(fetch = FetchType.LAZY, mappedBy="country")
private Set<City> cities;
在这里国家映射到多个城市,获取他们懒惰。这里是@Transactinal的作用当我们从数据库中检索Country对象时,我们会得到Country对象的所有数据,但不会得到城市的集合,因为我们是懒洋洋地获取城市。
//Without @Transactional
public Country getCountry(){
Country country = countryRepository.getCountry();
//After getting Country Object connection between countryRepository and database is Closed
}
当我们想要从国家对象访问Set of Cities时,我们将在该Set中获得空值,因为只有该Set创建的对象没有初始化该Set的数据来获取Set的值,我们使用@Transactional,即,
//with @Transactional
@Transactional
public Country getCountry(){
Country country = countryRepository.getCountry();
//below when we initialize cities using object country so that directly communicate with database and retrieve all cities from database this happens just because of @Transactinal
Object object = country.getCities().size();
}
所以基本上@Transactional is Service可以在单个事务中进行多个调用,而无需关闭与端点的连接。
我更喜欢在方法级的服务层上使用@Transactional。
推荐文章
- Intellij IDEA Java类在保存时不能自动编译
- 何时使用Mockito.verify()?
- 在maven中安装mvn到底做什么
- 不可变与不可修改的集合
- 如何在JSON中使用杰克逊更改字段名
- GSON -日期格式
- 如何从线程捕获异常
- 无法解析主机"<URL here>"没有与主机名关联的地址
- 如何在Java中打印二叉树图?
- 用Spring我可以做一个可选的路径变量吗?
- String.format()在Java中格式化双重格式
- com.jcraft.jsch.JSchException: UnknownHostKey
- Java中的操作符重载
- 如何加速gwt编译器?
- 在Hibernate中重新连接分离对象的正确方法是什么?