您应该将@Transactional放在DAO类和/或它们的方法中,还是更好地注释使用DAO对象调用的服务类?或者对两个“层”都加注释有意义吗?
当前回答
此外,Spring建议只在具体的类上使用注释,而不是在接口上使用。
http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html
其他回答
@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
通常情况下是在服务层级别上注释,但这实际上取决于您的需求。
在服务层上注释将比在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可以在单个事务中进行多个调用,而无需关闭与端点的连接。
通常,应该将事务放在服务层。
但是正如前面所述,操作的原子性告诉我们哪里需要注释。因此,如果你使用像Hibernate这样的框架,其中一个“save/update/delete/…”一个对象上的“modify”操作有可能修改几个表中的几行(因为通过对象图的级联),当然在这个特定的DAO方法上也应该有事务管理。
我更喜欢在方法级的服务层上使用@Transactional。
推荐文章
- 指定的子节点已经有一个父节点。你必须先在子对象的父对象上调用removeView() (Android)
- 对于一个布尔字段,它的getter/setter的命名约定是什么?
- 如何获得当前屏幕方向?
- 如何在Android中渲染PDF文件
- 如何计算一个元素在列表中出现的次数
- c++中类似于java的instanceof
- 我如何解决错误“minCompileSdk(31)指定在一个依赖的AAR元数据”在本机Java或Kotlin?
- 如何POST表单数据与Spring RestTemplate?
- Mockito中检测到未完成的存根
- 我应该如何复制字符串在Java?
- “while(true)”循环有那么糟糕吗?
- 这个方法签名中的省略号(…)是干什么用的?
- Java:如何测试调用System.exit()的方法?
- 带有返回类型的Java方法在没有返回语句的情况下编译
- Java“此语言级别不支持lambda表达式”