|
Свойство Deleted, %OnDelete
|
|||
---|---|---|---|
#18+
Приветствую всех, столкнулся с такой проблемой, прошу помощи, кто-то с большими практическими навыками думаю уже реализовывал такое. Стояла задача не удалять никакие объекты из базы, из-за этого добавил 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, если в удалении выкидывается ошибка, то каша возвращает в прежнее состояние объект. Теперь к вопросу: возможно ли как-то исправить данное решение, чтобы конечная цель была достигнута или есть ли у кого-то более профессиональное решение данной задачи? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 11:44 |
|
Свойство Deleted, %OnDelete
|
|||
---|---|---|---|
#18+
nurlybekovnt, Я бы посоветов создать отдельную таблицу в которую помещать сериализованное представление объекта для последующего возможного восстановления. Таким образом, объект будет реально удален, но можно будет сохранить информацию о нем для истории, кто когда и может зачем удалил. С вашим способом, нужно будет всегда помнить о том что есть удаленные объекты и их например нужно будет скрывать в результатах поиска. Если вам нужно чтобы такие объекты находились в результатах поиска, но просто с флагом помеченных на удаление. Тогда стоит пойти иначе, просто не использовать стандартное удаление, а просто ставить флаг Deleted. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 13:08 |
|
Свойство Deleted, %OnDelete
|
|||
---|---|---|---|
#18+
nurlybekovnt, Наш человек, создал вопрос и тут и на Developer Community. Я там кстати вопрос раньше заметил (благодаря уведомлениям), ответил, обратил внимание на вопрошающего, и решил проверить здесь. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 13:10 |
|
Свойство Deleted, %OnDelete
|
|||
---|---|---|---|
#18+
DAiMor, Да, я там тоже написал, здесь на форуме как-то кто-то рекомендовал писать свои вопросы там, по этой причине там написал. Цель Deleted исходит из безвыходности, потому что к удаляемому объекту Person могут другие объекты иметь внешний ключ Many-To-One, а каша из-за этого не позволит удалить Person, и это правильно. И я решил сделать свойство Deleted, да, верно перед каждым запросом мне теперь придется смотреть свойство, и еще в добавок перед %DeleteId нужно менять свойство Deleted на 1. А если есть объекты, ссылающиеся на данный Person, каша сама не позволит удалить его и я со спокойной душой запускаю %DeleteId. Чтобы на немного облегчить работу я хотел переопределить %OnDelete, и не беспокоится об изменении свойства перед %DeleteId. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 14:07 |
|
Свойство Deleted, %OnDelete
|
|||
---|---|---|---|
#18+
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 ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 14:13 |
|
Свойство Deleted, %OnDelete
|
|||
---|---|---|---|
#18+
nurlybekovnt, В порядке безобразия и вредных советов можете попробовать следующее Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 14:17 |
|
Свойство Deleted, %OnDelete
|
|||
---|---|---|---|
#18+
DAiMor, Спасибо вам за отзывчивость Ptn, Спасибо вам, за столь глубочайшее объяснение и приведенное решение ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 14:31 |
|
Свойство Deleted, %OnDelete
|
|||
---|---|---|---|
#18+
Если система не в зеркале и не шэдоуится, я бы перед Save посоветовал отключить журналирование, а после Save включать. Тогда при откате транзакции система не увидит изменения и не откатит. Если журналировани отключить нельзя, то я сделал бы отдельную систему. При удалении метод должен записать куда-то в нежурналируемый глобал (например, CACHETEMP) пару class/id, а отдельный процесс должен проверять это место и отмечать удаленными данные по этому глобалу. А еще правильнее просто использовать не стандартное удаление, а свой метод, типа MarkDeleted, при этом заглушку в %OnDelete оставить. Потому что откат транзакции - очень дорогая процедура, и строит на ней штатные механизмы неправильно. Способ Ptn (tcommit tstart) хоть и изящный, но я бы побоялся его использовать, из-за возможных неявных эффектов. Например, что-то может происходить до tcommit (в этом или следующей версии Каше), при этом вы эти изменения закоммитите. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2017, 18:27 |
|
|
start [/forum/topic.php?fid=39&fpage=6&tid=1556307]: |
0ms |
get settings: |
9ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
26ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
41ms |
get tp. blocked users: |
2ms |
others: | 294ms |
total: | 401ms |
0 / 0 |