Я использую оптимистичную стратегию при обновлении объектов, установив "<version />"
элемент в hbm.xml s. Он отлично работает при обновлении одного объекта. Но эта стратегия не при рассмотрении данного сценария:Как использовать оптимистичную блокировку с гибернацией при изменении полей
public class SalesPlan {
//omitted fields
private Resource resource;
private DateRange dateRange;
}
public class Resource {
//omitted fields
private int version = 1;
}
и существует ограничение: A Ресурс не должен иметь SalesPlan сек с перекрытой dateRange.For Например:
Учитывая есть Ресурс под названием «Hippoom курорт»
И это имеет SalesPlan начиная с 1 ноября 2013 года до ноября 2013 года 2
Когда я хочу добавить SalesPlan в диапазоне от 2 ноя 2013 по ноябрь 2, 2013
Затем он должен потерпеть неудачу по перекрытой диапазон дат
Я должен реализовать это в Java, потому что база данных уникальна ключ не работает в этом «диапазоне» case.The код выглядит следующим образом:
@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;
}
Принести все существовали SalesPlan S из базы данных в DuplicateSalesPlanSpecification, чтобы проверить, не отменяет ли новое SalesPlan.Я хочу обновить ресурс на последнем шаге (проверьте номер версии в Ресурсе) в случае параллельных операций. Но я отмечаю, что нет обновления sql, потому что ресурс не грязный.
------ Пересмотренный --------
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 в другой транзакции без последнего SQL
| the first transaction started | | | the second transaction started | select resource | | | select resource | select all salesplans | | | select all salesplans | validate base on all committed salesplans | | | validate base on all committed salesplans | insert salesplan | | | insert salesplan | update resource to check version | | | update resource to check version | commit txn | | | rolls back because version is dirty
------ Пересмотренный --------
версия Гибернация 3.6.10.FINAL.Is ли какие-либо возможности я могу F ix это?
Из вашего кода я не вижу изменений, внесенных в объект SalesPlan или Resource. Поэтому, если нет более кода (тогда, пожалуйста, опубликуйте его), нет никаких причин для обновления, потому что изменений нет. –
Извините, я не дал понять. Я хочу сохранить «SalesPlan» и проверить, не изменился ли «ресурс» другими. См. Пересмотренный контент. – Hippoom
Почему вы не используете HQL для этого с ограничениями вместо того, чтобы пытаться исправить это в сущности? –