"<version />"
通过在 hbm.xml 中设置元素来更新实体时,我使用了乐观的策略。当我更新单个实体时它工作正常。但是这种策略在处理这种情况时失败了:
public class SalesPlan {
//omitted fields
private Resource resource;
private DateRange dateRange;
}
public class Resource {
//omitted fields
private int version = 1;
}
并且有一个约束:资源不应具有具有重叠 dateRange 的 SalesPlan 。例如:
鉴于有一个名为“Hippoom 度假村”的资源
它的销售计划 从 2013 年 11 月 1 日到 2013 年 11 月 2 日
当我想添加从2013 年 11 月 2 日到 2013 年 11 月 2 日的销售计划时
那么它应该在重叠的日期范围内失败
我必须在 Java 中实现这一点,因为数据库唯一键在这种“范围”情况下不起作用。代码如下所示:
@Transactional
@Override
public SalesPlan handle(CreateSalesPlanCommand command) {
Resource resource = resourceRepository.findBy(command.getResourceId());
SalesPlan salesPlan = //omitted init codes
DuplicateSalesPlanSpecification spec = aDuplicateSpec();
if (spec.isSatisfiedBy(salesPlan)) {
throw new DuplicateSalesPlanException(salesPlan);
}
salesPlanRepository.store(salesPlan);
resourceRepository.store(salesPlan.getResource());
return salesPlan;
}
我从DuplicateSalesPlanSpecification中的数据库中获取所有现有的SalesPlan以检查新的SalesPlan 是否违反约束。我想在最后一步更新资源(检查资源中的版本号)以防并发操作。但我注意到没有更新 sql,因为资源不脏。
——————修改—————————</p>
select
resource0_.RESOURCE_ID as RESOURCE1_0_0_,
resource0_.version as version0_0_,
//omitted columns
from
T_IRS_RESOURCE resource0_
where
resource0_.RESOURCE_ID=?
select
this_.SALES_PLAN_ID as SALES1_1_0_,
this_.version as version1_0_,
this_.RESOURCE_ID as RESOURCE3_1_0_,
this_.DATE_RANGE_START as DATE4_1_0_,
this_.DATE_RANGE_END as DATE5_1_0_,
//omitted columns
from
T_IRS_SALES_PLAN this_
where
this_.RESOURCE_ID=?
order by
this_.DATE_RANGE_START desc,
this_.SALES_PLAN_ID desc
insert into T_IRS_SALES_PLAN//omitted columns
update T_IRS_RESOURCE set version = version + 1
where RESOURCE_ID = ?
and VERSION = ? //this sql missed
在使用乐观策略时,如果有人在另一个事务中插入新的 SalesPlan 而没有最后一个 sql,则 SalesPlan fetch sql 可能会过时
| 第一笔交易开始| | | 第二笔交易开始 | 选择资源 | | | 选择资源 | 选择所有销售计划 | | | 选择所有销售计划 | 根据所有承诺的销售计划进行验证 | | | 根据所有承诺的销售计划进行验证 | 插入销售计划 | | | 插入销售计划 | 更新资源以检查版本 | | | 更新资源以检查版本 | 提交交易 | | | 因为版本脏了所以回滚
——————修改—————————</p>
Hibernate 版本是 3.6.10.FINAL。我可以解决这个问题吗?