05.03.2004, 12:53 | #1 |
Участник
|
Блокирование запуска отчета
Как сделать так, чтобы при запуске отчета из одной сессии его невозможно было запустить из другой сессии до тех пор, пока он не отработает в первой?
LOCKTABLE здесь применить не получается, потому что процесс состоит из нескольких транзакций - COMMIT разбросаны по отчету в нескольких местах. Это сделано, чтобы не блокировать некоторые таблицы на все время работы отчета. Однако, по ряду причин мне необходимо, чтобы модификации, выполняемые именно этим отчетом, производились монопольно. Возможно ли установить подобное ограничение средствами C/SIDE, или надо лезть на SQL Server, или это вообще невозможно? |
|
05.03.2004, 14:10 | #2 |
Участник
|
Решается легко - делаем где-нить флажок и проверяем его наличие перед запуском (через xSysLastValue, например).
Только вот отчёты с транзакциями и монопольные - это серьёзно что-то не так с архитетурой. |
|
05.03.2004, 14:39 | #3 |
Участник
|
Re: Блокирование запуска отчета
Цитата:
Изначально опубликовано uk
Как сделать так, чтобы при запуске отчета из одной сессии его невозможно было запустить из другой сессии до тех пор, пока он не отработает в первой? Т.е. в отчете вы изменяете состояние базы данных? Зачем? Это ж противоречит всем правилам программирования, это противоречит зравому смыслу, это противоречит правилам администрирования. Вам придется воевать с ядром, наконец. Сделайте два объекта - обработку и отчет. Обработка меняет. Отчет только получает данные. В результате, вы получите возможность запускать их в разное время и на разных машинах. Расчет будет делаться один раз, поэтому вы снизите нагрузку на систему. Вы получите возможность давать разные права на эти объекты. Отчет будет существенно проще и не потребует ТАКОГО программирования. Задачу можно распараллелить между разработчиками. И т.п. Ну зачем же вы себе жизнь то усложняете?! На ровном месте причем! |
|
05.03.2004, 14:43 | #4 |
Участник
|
извините, совсем заработался с Аксаптой.
В Навижин codeunit и report, естественно. |
|
05.03.2004, 16:26 | #5 |
Участник
|
Спешу не согласиться с Muzzy, в Navision объекты типа Report также выполняют роль периодических заданий (например Коррекция Себестоимости). Так что вопрос остается открытым. Хотя зачем при выполнении несколько раз коммитить.. ?! Может его просто выполнять на выделенном сервере отчетов, например. Многие так делают - для отчетов вешают дополнительный сервер БД. Тогда и проблем с блокировкой не будет!
__________________
Вот такие, брат, дела! |
|
05.03.2004, 16:49 | #6 |
Участник
|
Цитата:
Изначально опубликовано Yuriy
Спешу не согласиться с Muzzy, в Navision объекты типа Report также выполняют роль периодических заданий (например Коррекция Себестоимости). |
|
05.03.2004, 17:02 | #7 |
Участник
|
Мой отчет имеет свойство ProcessingOnly. Т.е. он предназначен именно для обработки, а не для вывода на печать.
Но забудем про отчет. Пусть это будет кнопка на форме. Нажатием на кнопку вызывается, допустим, codeunit, который выполняет расчеты и производит модификацию записей в базе. Я хочу сделать так, чтобы во время, пока выполняется этот процесс, нельзя было запустить этот же процесс из другой сессии. Во время процесса блокируются таблицы, к которым обращаются другие пользователи. Поскольку процесс продолжительный, я разбил его на транзакции функцией COMMIT. Происходит обработка первого товара, на время которой некоторые процессы других пользователей блокируются. Далее следует функция COMMIT, которая завершает транзакцию (но не процесс) и снимает блокировку. Другие сессии благополучно завершают свои транзакции. После чего мой процесс приступает к обработке следующего товара. Здесь все в порядке. Но при таком раскладе я не вижу возможности исключить параллельный запуск данного расчета. Потому что мне нужно блокировать не таблицы, которые расчет модифицирует, а сам факт запуска этого расчета. Нужен действительно какой-то флажок, но я не знаю, где его можно создать. Что касается xSysLastValue – то это из мира Axapta, насколько я понимаю, а речь про Navision. 2 Yuriy Не совсем понял про выделенный сервер отчетов. У меня ведь идет именно модификация данных. Как можно выполнять ее отдельно? К слову, всё это касается как раз коррекции себестоимости, только не родной навижнской, а самодельной, доставшейся нам в наследство от внедряющей фирмы. |
|
05.03.2004, 17:57 | #8 |
Участник
|
Разумно.
Но чего я не понимал... Цитата:
Изначально опубликовано uk
Но при таком раскладе я не вижу возможности исключить параллельный запуск данного расчета. |
|
05.03.2004, 18:19 | #9 |
----------------
|
Как это делается в Аксапте, думаю по аналогии можно и в Navision.
Есть таблица InventClosing - закрятия и коррекции. В начале процедуры расчета себестоимости туда записывается информация о том за какой период происходит обработка. При наличии этой записи никакие другие процессы уже не могут изменять данные за период, в том числе и другой экземпляр закрытия. По завершению процесса в InventClosing проставляется галочка, что процесс завершен. |
|
05.03.2004, 18:28 | #10 |
NavAx
|
Если сильно хочется запускать отчет "монопольно", то это, в принципе, решается.
Заведите, например, кодъюнит со свойством SingleInstance = TRUE. Заведите в нем переменную типа ReportIsRunning : boolean. Заведите функции GetReportStatus и SetReportStatus, которые возвращают значение и устанавливают значение этой переменной. На OnPreReport напишите что-нибудь типа IF CodeUnitName.GetReportStatus THEN CurrReport.QUIT ELSE CodeUnitName.SetReportStatus(TRUE); На OnPostReport либо CodeUnitName.SetReportStatus(FALSE) либо CLEAR(CodeUnitName). Правда, есть опасность, что в случае некорректного завершения работы отчета (т.е. OnPostReport не отработается) случится бяка и отчет больше никогда не запустится =) Также можно установить подобный флажок не через кодъюнит, а используя поле какой-нибудь настроечной таблички (а можно и не настроечной...). Но штука имхо не особо полезная. Вполне возможно наворотить делов и не из того же отчета =) 2 Mazzy: не согласен насчет Цитата:
Цитата:
-------------------------------------------------------------------------------- Изначально опубликовано Yuriy Спешу не согласиться с Muzzy, в Navision объекты типа Report также выполняют роль периодических заданий (например Коррекция Себестоимости). -------------------------------------------------------------------------------- Да, есть. Поубивал бы. |
|
05.03.2004, 19:51 | #11 |
Участник
|
наверное. спасибо, надо подумать.
|
|
09.03.2004, 05:20 | #12 |
Участник
|
Цитата:
Может его просто выполнять на выделенном сервере отчетов, например. Многие так делают - для отчетов вешают дополнительный сервер БД. Тогда и проблем с блокировкой не будет!
|
|
09.03.2004, 06:04 | #13 |
Участник
|
Тьху, блин! Опять Navision! Тогда мой совет ни к чему=) Удивительно, что есть отчёты processing only... Оч. странная идея... В Axapta это примерно чёрствым батоном гвозди забивать, как было сказано в одной из статей.
|
|
09.03.2004, 11:29 | #14 |
Участник
|
Цитата:
Изначально опубликовано Yoil
Если сильно хочется запускать отчет "монопольно", то это, в принципе, решается. Заведите, например, кодъюнит со свойством SingleInstance = TRUE. Заведите в нем переменную типа ReportIsRunning : boolean. Заведите функции GetReportStatus и SetReportStatus, которые возвращают значение и устанавливают значение этой переменной. На OnPreReport напишите что-нибудь типа IF CodeUnitName.GetReportStatus THEN CurrReport.QUIT ELSE CodeUnitName.SetReportStatus(TRUE); На OnPostReport либо CodeUnitName.SetReportStatus(FALSE) либо CLEAR(CodeUnitName). Правда, есть опасность, что в случае некорректного завершения работы отчета (т.е. OnPostReport не отработается) случится бяка и отчет больше никогда не запустится =) Также можно установить подобный флажок не через кодъюнит, а используя поле какой-нибудь настроечной таблички (а можно и не настроечной...). -------------------------------------------------------------------------------- Изначально опубликовано uk Но при таком раскладе я не вижу возможности исключить параллельный запуск данного расчета. -------------------------------------------------------------------------------- 2 mazzy Цитата:
А почему только данного? А у вас нет других расчетов, которые работают с этими же таблицами? Они же тоже могут что-то править. В промежутках между транзакциями. Я чего-то не понимаю?
Мне трудно предсказать последствия параллельной работы этого расчета - поэтому я и хочу избежать подобной ситуации. |
|
22.03.2004, 12:14 | #15 |
Участник
|
Не пойму в чем проблема.
В любую таблицу (например в InventorySetup) добавляем поле типа CrazyReportIsRunning boolean В репорте в самом начале проверяем этот флажок. Если надо - выставляем, модифаим, работаем. Делов-то на 2 минуты. Или я чего-то не знаю? |
|
22.03.2004, 17:12 | #16 |
Участник
|
Вопрос в том, когда этот флажок снимать. Видимо, в OnPostReport.
Допустим, пользователь завершил отчет по Esc, не дожидаясь окончания. OnPostReport не отработал, флажок остался - отчет IsRunning. Больше никогда не запустится. |
|
22.03.2004, 17:20 | #17 |
Участник
|
точно... у него же в отчете коммиты понатыканы... вот ведь.;-0
|
|
22.03.2004, 19:47 | #18 |
Участник
|
Коррекция себестоимости, если мне не изменяет память, запускается из пункта меню. Можно прописать на методе OnPush этого пункта меню код:
если есть галочка в некотором поле, то не запускать отчет, иначе: поставить галочку, например, в таблице Location Setup (предварительно добавив туда поле)... CLEAR(TestReport); TestReport.RUNMODAL; снять галочку в поле в таблице настроек. Вот вроде и все.
__________________
Вот такие, брат, дела! |
|
|
Похожие темы | ||||
Тема | Ответов | |||
Печать отчета из просмотра | 1 | |||
Свойство KeepWithNext тела отчета! | 2 | |||
Проблема с компиляцией отчёта | 2 | |||
[Attein 3.01]Запрет печати отчета из предварительно просмотра. | 11 |
|