"<version />"
hbm.xml s で要素を設定してエンティティを更新するときは、楽観的な戦略を使用しています。単一のエンティティを更新すると正常に動作します。しかし、このシナリオを扱う場合、この戦略は失敗します。
public class SalesPlan {
//omitted fields
private Resource resource;
private DateRange dateRange;
}
public class Resource {
//omitted fields
private int version = 1;
}
制約があります: Resourceには、重複する dateRange を持つSalesPlanがあってはなりません。例:
「Hippoom リゾート」という名前のリソースがあるとします。
また 、2013 年 11 月 1 日から 2013 年 11 月 2 日の範囲のSalesPlanがあります。
2013 年 11 月 2 日から 2013 年 11 月 2 日までのSalesPlanを追加したい場合
次に、重複する日付範囲では失敗するはずです
この「範囲」の場合、データベースの一意のキーが機能しないため、これを 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
楽観的な戦略を使用している間、誰かが最後の sql なしで別のトランザクションに新しい SalesPlan を挿入すると、SalesPlan fetch sql が古くなる可能性があります
| | 最初の取引開始 | | | | | 2番目のトランザクションが開始されました | | リソースを選択 | | | | | リソースを選択 | | すべてのセールスプランを選択 | | | | | すべての販売プランを選択 | | コミットされたすべての販売計画に基づいて検証する | | | | | コミットされたすべての販売計画に基づいて検証する | | 販売計画を挿入 | | | | | 販売計画を挿入 | | リソースを更新してバージョンを確認 | | | | | リソースを更新してバージョンを確認する | | トランザクションをコミット | | | | | バージョンがダーティであるため、ロールバックします
—————改訂済み————————</p>
Hibernate のバージョンは 3.6.10.FINAL です。これを修正できる可能性はありますか?