gpt4 book ai didi

spring - @Transactional 和 JPA 对象参数

转载 作者:行者123 更新时间:2023-12-02 06:59:56 26 4
gpt4 key购买 nike

在编写多层应用程序时,最佳实践似乎是仅将对象 ID 传递给事务服务方法。但我宁愿传递实际的 JPA 对象。与问题 Is domain model object passing between layers overhead? 不同一些同事担心 a) 对象可能属于另一个/无事务,因此在服务方法内部修改时会导致问题,b) 从 UI 组件调用此类服务​​方法后修改对象可能会导致问题,因为事务已经提交.

用代码表达我宁愿拥有

@Named public class MyServiceImpl
{
...

@Transactional
public BigDecimal calculate(ObjectOne objectOne, ObjectTwo objectTwo)
{
...
}
}

而不是

@Named public class MyServiceImpl
{
...

@Transactional
public BigDecimal calculate(long objectOneId, long objectTwoId)
{
ObjectOne objectOne = objectOneService.find(objectOneId);
ObjectTwo objectTwo = objectTwoService.find(objectTwoId);
...
}
}

那么有没有一种技术可以让事务管理器(spring)正确地处理对象呢?或者您是否建议明确使用 JPA 合并或其他任何方式来正确处理直接对象引用?或者您是否也不鼓励传递对象而不是 ID?

显然,特别是带有官方众所周知来源链接的解释会很有帮助。

最佳答案

作为default behavior of @TransactionalPROPAGATION_REQUIRED将业务对象传递到事务方法中应该没问题。如果调用操作已经打开了一个事务,则会打开一个新的虚拟事务(对于同一物理事务)并且对象引用保持不变。如果没有事务处于事件状态,则不会损害持久状态。

为了确保对象正常,你可以这样做

@Transactional
public BigDecimal calculate(ObjectOne objectOne, ObjectTwo objectTwo)
{
objectOne = objectOneService.find(objectOne.getId());
objectTwo = objectTwoService.find(objectTwo.getId());
...
}

这很便宜,因为对象是从缓存中获取的。但这不是必需的,因为对象位于同一物理事务中。

如果对象确实来自不同的事务,您可以使用上面的代码解决它。但是您的调用方法不会看到对该对象所做的任何更改,除非它再次从数据库中获取其对象(并且根据隔离启动一个新事务)。

关于spring - @Transactional 和 JPA 对象参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26869647/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com