Какой метод использовать при сохранении бизнес-объекта, если на стороне сервера БД возможна установка некоторых полей (например timestamp).
Значения этих полей должны быть установлены в объекте после сохранения.
Вариант 1 — генерить событие об успешном сохранении, на которое реагировать повторным запросом объекта (Reload)
Вариант 2 — возвращать "согласованный" объект как результат вызова метода сервиса.
Я бы наверное предпочел второй вариант, но тесты показываю значительно снижение производительности при возвращении объекта как результата.
Как поступаете вы?
Примеры:
Здравствуйте, IT, Вы писали: IT>Либо ничего не возращаем, либо ID нового объекта, если оно автоинкремент. В случае ошибки прилетает исключение.
А timestamp — метка последнего изменения объекта, необходимая для оптимистической блокировки?
А CreationDate — дата создания объекта?
А LastChangeDate?
Ну и другие свойства может быть необходимо передать обратно, если они устанавливаются на сервере.
Что же касается ID, то тут как раз все довольно просто — это GUID генерируемый на клиенте.
IT>Тем более. ID — это всё, что необходимо и достаточно. Сам объект если надо можно всегда считать дополнительным вызовом.
IT, я же говорю, нужен timestamp который возвращает хп при сохранении объекта.
При следующем сохранении (update) объекта в БД, он (timestamp) передается в хп Update_Object. Внутри хп идет проверка переданного timestamp и timestamp в БД и если они не совпадают, в хп генерится исключение через RAISERROR.
Таким образом реализуется оптимистическая блокировка объекта.
Здравствуйте, снежок, Вы писали:
С>IT, я же говорю, нужен timestamp который возвращает хп при сохранении объекта.
Это зависит от твоей конеретной ситуации, которая в свою очередь может зависеть от типа приложения. Например, для веб приложений возврат как правило ничего не даёт, т.к. обычно нужно отрефрешить форму. Для UI приложений наоборот, чаще всего нужно вернуть объект сразу. Если уж такие большие сомнения, то напиши пару Save и Get, а потом напиши ещё один метод — SaveAndGet, который будет вызывать первые два по очереди
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, снежок, Вы писали:
IT>>Тем более. ID — это всё, что необходимо и достаточно. Сам объект если надо можно всегда считать дополнительным вызовом. С>IT, я же говорю, нужен timestamp который возвращает хп при сохранении объекта. С>При следующем сохранении (update) объекта в БД, он (timestamp) передается в хп Update_Object. Внутри хп идет проверка переданного timestamp и timestamp в БД и если они не совпадают, в хп генерится исключение через RAISERROR. С>Таким образом реализуется оптимистическая блокировка объекта.
ну так можно выделить всю такую информацию в отдельный объект, и возвращать его назад. наверняка же все объекты тогда имеют соотв. аттрибуты, значит их заполнение можно организовать в родительском классе.
В зависимости от ситуации. Есть еще следующий нюанс. В многопользовательской среде я стараюсь получить объект как можно позже. Тогда он с большей вероятностью будет актуален, и затем транзакционные действия с ним будут успешны. Очень обидно когда пользователь редактирует форму и оказывается что один из объектов участвующих в сохранении уже был удален. Поэтому нужно смотреть сценарии использования объекта, требования к его актуальности, и решать как действовать. Зачастую в зависимости от типа этого объекта.
GZ>Очень обидно когда пользователь редактирует форму и оказывается что один из объектов участвующих в сохранении уже был удален.
Если это так важно, то в подобных ситуациях обычно используют пессимистическую блокировку на основе "контракта" и продлении "контракта" на объект.
А как получать объект "как можно позже" не совсем понятно...
Ведь получаем на клиент объект от сервиса по мере необходимости, например, для редактирования, и сколько форма редактирования будет открыта никому не известно. И как следствие оптимистической блокировки, непредсказуемо кто первый сохранит объект.
Если же в контексте "как можно позже" речь идет о ситуации когда клиент/среднее звено заранее или по мере необходимости кеширует объекты, то тут довольно тривиально — при запросе объекта из кеша должна производится проверка в БД (по timestamp к примеру) а не был ли объект изменен, если был — объект должен выбрасываться из кеша и должен происходить его Reload.
Здравствуйте, снежок, Вы писали:
GZ>>Очень обидно когда пользователь редактирует форму и оказывается что один из объектов участвующих в сохранении уже был удален. С>Если это так важно, то в подобных ситуациях обычно используют пессимистическую блокировку на основе "контракта" и продлении "контракта" на объект.
Не обязательно.
С>А как получать объект "как можно позже" не совсем понятно...
Можно сказать так как ты написал. По мере необходимости.
С>Ведь получаем на клиент объект от сервиса по мере необходимости, например, для редактирования, и сколько форма редактирования будет открыта никому не известно. И как следствие оптимистической блокировки, непредсказуемо кто первый сохранит объект.
Но стремиться к лучшему — никто не мешает. Чем позже получаем объект, те больше шансов зафиксироваться. Кроме основного объекта еще обычно используются справочники(которые связаны констрейнтами). При сохранении объекта обычно форма закрывается и объект больше не нужен. Вобщем получение объекта после сохранения не нужно в большинстве случаев. Достаточно его идентификатора.
С>Если же в контексте "как можно позже" речь идет о ситуации когда клиент/среднее звено заранее или по мере необходимости кеширует объекты, то тут довольно тривиально — при запросе объекта из кеша должна производится проверка в БД (по timestamp к примеру) а не был ли объект изменен, если был — объект должен выбрасываться из кеша и должен происходить его Reload.
Латентность вызова в коротких запросах на БД является определяющей. Поэтому такой кэш весьма вероятно не будет эффективным. Лучше такую архитектуру проверить.
С>>Если же в контексте "как можно позже" речь идет о ситуации когда клиент/среднее звено заранее или по мере необходимости кеширует объекты, то тут довольно тривиально — при запросе объекта из кеша должна производится проверка в БД (по timestamp к примеру) а не был ли объект изменен, если был — объект должен выбрасываться из кеша и должен происходить его Reload. GZ>Латентность вызова в коротких запросах на БД является определяющей. Поэтому такой кэш весьма вероятно не будет эффективным. Лучше такую архитектуру проверить.
В таких случаях, кеширование отдельных типов отключается. А вот для довольно разветвленных объектов такой кеш будет эффективным, проверялось