Chr*_*ian 5 spring jpa transactions
编程多层应用程序时,最好只将对象ID传递给事务服务方法.但我宁愿传递实际的JPA对象.与问题不同是域模型对象在层之间传递开销吗?一些同事担心a)对象可能属于另一个/无事务,如果因此在服务方法内部修改时会导致问题,并且b)在从UI组件调用此类服务方法后对象可能会导致问题,因为事务已经提交.
用代码表示我更愿意拥有
@Named public class MyServiceImpl
{
...
@Transactional
public BigDecimal calculate(ObjectOne objectOne, ObjectTwo objectTwo)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
代替
@Named public class MyServiceImpl
{
...
@Transactional
public BigDecimal calculate(long objectOneId, long objectTwoId)
{
ObjectOne objectOne = objectOneService.find(objectOneId);
ObjectTwo objectTwo = objectTwoService.find(objectTwoId);
...
}
}
Run Code Online (Sandbox Code Playgroud)
那么有一种技术,事务管理器(spring)正确地关注对象吗?或者,您是否建议使用JPA merge或其他任何显式来正确处理直接对象引用?或者你也不鼓励传递对象而不是ID?
特别是与官方或知名来源有关的解释显然会有所帮助.
由于@Transactional 的默认行为是PROPAGATION_REQUIRED,因此将业务对象传递到事务方法中应该没问题。如果调用操作已经打开了一个事务,则会打开一个新的虚拟事务(对于同一物理事务)并且对象引用保持不变。如果没有事务处于活动状态,则不会损害持久状态。
为了确保对象是理智的,你可以这样做
@Transactional
public BigDecimal calculate(ObjectOne objectOne, ObjectTwo objectTwo)
{
objectOne = objectOneService.find(objectOne.getId());
objectTwo = objectTwoService.find(objectTwo.getId());
...
}
Run Code Online (Sandbox Code Playgroud)
这很便宜,因为对象是从缓存中获取的。但这不是必需的,因为对象位于同一物理事务中。
如果对象确实来自不同的事务,您可以使用上面的代码解决它。但是您的调用方法不会看到对该对象所做的任何更改,除非它再次从数据库中获取其对象(并且根据隔离启动一个新事务)。
| 归档时间: |
|
| 查看次数: |
930 次 |
| 最近记录: |