Гость
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Свойство Deleted, %OnDelete / 8 сообщений из 8, страница 1 из 1
01.11.2017, 11:44
    #39545843
nurlybekovnt
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Свойство Deleted, %OnDelete
Приветствую всех, столкнулся с такой проблемой, прошу помощи, кто-то с большими практическими навыками думаю уже реализовывал такое. Стояла задача не удалять никакие объекты из базы, из-за этого добавил Property Deleted As %Boolean [ InitialExpression = 0 ]; в класс. И в переопределил метод %OnDelete:
ClassMethod %OnDelete(oid As %ObjectIdentity) As %Status [ Private, ServerOnly = 1 ]
{
s person = ..%Open(oid)
s person.Deleted = 1
d person.%Save()
Quit $$$ERROR(2112, "DeleteOperationNotAllowed")
}

В документации сказано, если %OnDelete возвращает $$$OK, то объект удалится, а необходимо обратное. Все было прекрасно, но обнаружилось что, Deleted не изменяется. После того как я вызываю do ##class(Person).%DeleteId(29564), объект не удаляется и свойство тоже не изменяется. Сам покапался, думаю это из-за roll back, если в удалении выкидывается ошибка, то каша возвращает в прежнее состояние объект. Теперь к вопросу: возможно ли как-то исправить данное решение, чтобы конечная цель была достигнута или есть ли у кого-то более профессиональное решение данной задачи?
...
Рейтинг: 0 / 0
01.11.2017, 13:08
    #39545941
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Свойство Deleted, %OnDelete
nurlybekovnt,

Я бы посоветов создать отдельную таблицу в которую помещать сериализованное представление объекта для последующего возможного восстановления.
Таким образом, объект будет реально удален, но можно будет сохранить информацию о нем для истории, кто когда и может зачем удалил.

С вашим способом, нужно будет всегда помнить о том что есть удаленные объекты и их например нужно будет скрывать в результатах поиска.
Если вам нужно чтобы такие объекты находились в результатах поиска, но просто с флагом помеченных на удаление. Тогда стоит пойти иначе, просто не использовать стандартное удаление, а просто ставить флаг Deleted.
...
Рейтинг: 0 / 0
01.11.2017, 13:10
    #39545943
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Свойство Deleted, %OnDelete
nurlybekovnt,

Наш человек, создал вопрос и тут и на Developer Community. Я там кстати вопрос раньше заметил (благодаря уведомлениям), ответил, обратил внимание на вопрошающего, и решил проверить здесь.
...
Рейтинг: 0 / 0
01.11.2017, 14:07
    #39546001
nurlybekovnt
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Свойство Deleted, %OnDelete
DAiMor,

Да, я там тоже написал, здесь на форуме как-то кто-то рекомендовал писать свои вопросы там, по этой причине там написал.
Цель Deleted исходит из безвыходности, потому что к удаляемому объекту Person могут другие объекты иметь внешний ключ Many-To-One, а каша из-за этого не позволит удалить Person, и это правильно.
И я решил сделать свойство Deleted, да, верно перед каждым запросом мне теперь придется смотреть свойство, и еще в добавок перед %DeleteId нужно менять свойство Deleted на 1. А если есть объекты, ссылающиеся на данный Person, каша сама не позволит удалить его и я со спокойной душой запускаю %DeleteId.
Чтобы на немного облегчить работу я хотел переопределить %OnDelete, и не беспокоится об изменении свойства перед %DeleteId.
...
Рейтинг: 0 / 0
01.11.2017, 14:13
    #39546014
Ptn
Ptn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Свойство Deleted, %OnDelete
nurlybekovnt,В документации сказано, если %OnDelete возвращает $$$OK, то объект удалится, а необходимо обратное. Все было прекрасно, но обнаружилось что, Deleted не изменяется. После того как я вызываю do ##class(Person).%DeleteId(29564), объект не удаляется и свойство тоже не изменяется.

Вот смотрите :
1 - Идет вызов %DeleteId
2 - Открывается транзакция 1
3 - Вызывается %OnDelete
3.1 - В нем вы открываете объект
3.2 - Устанавливаете Deleted = 1
3.3 - Сохраняете объект
3.3.1 - Открывается транзакция 2
3.3.2 - Происходят вызовы %OnBeforeSave %OnAddToSaveSet %OnAfterSave
3.3.3 - Коммитится транзакция 2
3.4 - Вы выходите из %OnDelete с ошибкой $$$ERROR(2112, "DeleteOperationNotAllowed")
4 - Объект видя ошибку откатывает транзакцию 1

Все ... теперь у вас объект опять в том же состоянии что и до вызова %DeleteId
...
Рейтинг: 0 / 0
01.11.2017, 14:17
    #39546017
Ptn
Ptn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Свойство Deleted, %OnDelete
nurlybekovnt,

В порядке безобразия и вредных советов можете попробовать следующее

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
ClassMethod %OnDelete(oid As %ObjectIdentity) As %Status [ Private, ServerOnly = 1 ]
{
 s person = ..%Open(oid)
 s person.Deleted = 1
 d person.%Save()
 try { tcommit  tstart  } catch {}
 Quit $$$ERROR(2112, "DeleteOperationNotAllowed")
}
...
Рейтинг: 0 / 0
01.11.2017, 14:31
    #39546046
nurlybekovnt
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Свойство Deleted, %OnDelete
DAiMor,
Спасибо вам за отзывчивость

Ptn,
Спасибо вам, за столь глубочайшее объяснение и приведенное решение
...
Рейтинг: 0 / 0
01.11.2017, 18:27
    #39546323
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Свойство Deleted, %OnDelete
Если система не в зеркале и не шэдоуится, я бы перед Save посоветовал отключить журналирование, а после Save включать. Тогда при откате транзакции система не увидит изменения и не откатит.

Если журналировани отключить нельзя, то я сделал бы отдельную систему. При удалении метод должен записать куда-то в нежурналируемый глобал (например, CACHETEMP) пару class/id, а отдельный процесс должен проверять это место и отмечать удаленными данные по этому глобалу.

А еще правильнее просто использовать не стандартное удаление, а свой метод, типа MarkDeleted, при этом заглушку в %OnDelete оставить. Потому что откат транзакции - очень дорогая процедура, и строит на ней штатные механизмы неправильно.

Способ Ptn (tcommit tstart) хоть и изящный, но я бы побоялся его использовать, из-за возможных неявных эффектов. Например, что-то может происходить до tcommit (в этом или следующей версии Каше), при этом вы эти изменения закоммитите.
...
Рейтинг: 0 / 0
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Свойство Deleted, %OnDelete / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]