AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 05.03.2004, 12:53   #1  
uk is offline
uk
Участник
 
14 / 10 (1) +
Регистрация: 06.05.2003
Адрес: Санкт-Петербург
Блокирование запуска отчета
Как сделать так, чтобы при запуске отчета из одной сессии его невозможно было запустить из другой сессии до тех пор, пока он не отработает в первой?

LOCKTABLE здесь применить не получается, потому что процесс состоит из нескольких транзакций - COMMIT разбросаны по отчету в нескольких местах. Это сделано, чтобы не блокировать некоторые таблицы на все время работы отчета.

Однако, по ряду причин мне необходимо, чтобы модификации, выполняемые именно этим отчетом, производились монопольно. Возможно ли установить подобное ограничение средствами C/SIDE, или надо лезть на SQL Server, или это вообще невозможно?
Старый 05.03.2004, 14:10   #2  
LCh is offline
LCh
Участник
 
104 / 10 (1) +
Регистрация: 13.11.2002
Адрес: Санкт-Петербург
Решается легко - делаем где-нить флажок и проверяем его наличие перед запуском (через xSysLastValue, например).
Только вот отчёты с транзакциями и монопольные - это серьёзно что-то не так с архитетурой.
Старый 05.03.2004, 14:39   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Re: Блокирование запуска отчета
Цитата:
Изначально опубликовано uk
Как сделать так, чтобы при запуске отчета из одной сессии его невозможно было запустить из другой сессии до тех пор, пока он не отработает в первой?
Вы делаете отчет с побочными эффектами?
Т.е. в отчете вы изменяете состояние базы данных?

Зачем? Это ж противоречит всем правилам программирования, это противоречит зравому смыслу, это противоречит правилам администрирования. Вам придется воевать с ядром, наконец.

Сделайте два объекта - обработку и отчет.
Обработка меняет. Отчет только получает данные.

В результате, вы получите возможность запускать их в разное время и на разных машинах. Расчет будет делаться один раз, поэтому вы снизите нагрузку на систему. Вы получите возможность давать разные права на эти объекты. Отчет будет существенно проще и не потребует ТАКОГО программирования. Задачу можно распараллелить между разработчиками. И т.п.

Ну зачем же вы себе жизнь то усложняете?! На ровном месте причем!
Старый 05.03.2004, 14:43   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
извините, совсем заработался с Аксаптой.
В Навижин codeunit и report, естественно.
Старый 05.03.2004, 16:26   #5  
Yuriy is offline
Yuriy
Участник
 
150 / 10 (1) +
Регистрация: 25.02.2003
Адрес: Москва
Спешу не согласиться с Muzzy, в Navision объекты типа Report также выполняют роль периодических заданий (например Коррекция Себестоимости). Так что вопрос остается открытым. Хотя зачем при выполнении несколько раз коммитить.. ?! Может его просто выполнять на выделенном сервере отчетов, например. Многие так делают - для отчетов вешают дополнительный сервер БД. Тогда и проблем с блокировкой не будет!
__________________
Вот такие, брат, дела!
Старый 05.03.2004, 16:49   #6  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Изначально опубликовано Yuriy
Спешу не согласиться с Muzzy, в Navision объекты типа Report также выполняют роль периодических заданий (например Коррекция Себестоимости).
Да, есть. Поубивал бы.
Старый 05.03.2004, 17:02   #7  
uk is offline
uk
Участник
 
14 / 10 (1) +
Регистрация: 06.05.2003
Адрес: Санкт-Петербург
Мой отчет имеет свойство ProcessingOnly. Т.е. он предназначен именно для обработки, а не для вывода на печать.
Но забудем про отчет. Пусть это будет кнопка на форме. Нажатием на кнопку вызывается, допустим, codeunit, который выполняет расчеты и производит модификацию записей в базе. Я хочу сделать так, чтобы во время, пока выполняется этот процесс, нельзя было запустить этот же процесс из другой сессии.
Во время процесса блокируются таблицы, к которым обращаются другие пользователи. Поскольку процесс продолжительный, я разбил его на транзакции функцией COMMIT. Происходит обработка первого товара, на время которой некоторые процессы других пользователей блокируются. Далее следует функция COMMIT, которая завершает транзакцию (но не процесс) и снимает блокировку. Другие сессии благополучно завершают свои транзакции. После чего мой процесс приступает к обработке следующего товара. Здесь все в порядке.
Но при таком раскладе я не вижу возможности исключить параллельный запуск данного расчета. Потому что мне нужно блокировать не таблицы, которые расчет модифицирует, а сам факт запуска этого расчета. Нужен действительно какой-то флажок, но я не знаю, где его можно создать.
Что касается xSysLastValue – то это из мира Axapta, насколько я понимаю, а речь про Navision.

2 Yuriy
Не совсем понял про выделенный сервер отчетов. У меня ведь идет именно модификация данных. Как можно выполнять ее отдельно? К слову, всё это касается как раз коррекции себестоимости, только не родной навижнской, а самодельной, доставшейся нам в наследство от внедряющей фирмы.
Старый 05.03.2004, 17:57   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Разумно.

Но чего я не понимал...
Цитата:
Изначально опубликовано uk
Но при таком раскладе я не вижу возможности исключить параллельный запуск данного расчета.
А почему только данного? А у вас нет других расчетов, которые работают с этими же таблицами? Они же тоже могут что-то править. В промежутках между транзакциями. Я чего-то не понимаю?
Старый 05.03.2004, 18:19   #9  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Как это делается в Аксапте, думаю по аналогии можно и в Navision.

Есть таблица InventClosing - закрятия и коррекции. В начале процедуры расчета себестоимости туда записывается информация о том за какой период происходит обработка. При наличии этой записи никакие другие процессы уже не могут изменять данные за период, в том числе и другой экземпляр закрытия. По завершению процесса в InventClosing проставляется галочка, что процесс завершен.
Старый 05.03.2004, 18:28   #10  
Yoil is offline
Yoil
NavAx
NavAx Club
Лучший по профессии 2017
Лучший по профессии 2009
 
1,574 / 70 (6) ++++
Регистрация: 20.11.2002
Адрес: Msk
Если сильно хочется запускать отчет "монопольно", то это, в принципе, решается.
Заведите, например, кодъюнит со свойством 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 также выполняют роль периодических заданий (например Коррекция Себестоимости).
--------------------------------------------------------------------------------


Да, есть. Поубивал бы.
Отчет - это весьма удобный инструмент для того, чтобы шарится по табличкам. Оч. удобно организованный цикл. Так что для периодических заданий он часто очень удобен. Имхо не зря таки товарищи прилепили туда свойство ProcessingOnly
Старый 05.03.2004, 19:51   #11  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
наверное. спасибо, надо подумать.
Старый 09.03.2004, 05:20   #12  
Aleksander is offline
Aleksander
Участник
 
82 / 10 (1) +
Регистрация: 30.04.2003
Адрес: Уссурийск
Цитата:
Может его просто выполнять на выделенном сервере отчетов, например. Многие так делают - для отчетов вешают дополнительный сервер БД. Тогда и проблем с блокировкой не будет!
А можно несколько по-подробней рассказать о "Выделенном Сервере Отчетов"?
Старый 09.03.2004, 06:04   #13  
LCh is offline
LCh
Участник
 
104 / 10 (1) +
Регистрация: 13.11.2002
Адрес: Санкт-Петербург
Тьху, блин! Опять Navision! Тогда мой совет ни к чему=) Удивительно, что есть отчёты processing only... Оч. странная идея... В Axapta это примерно чёрствым батоном гвозди забивать, как было сказано в одной из статей.
Старый 09.03.2004, 11:29   #14  
uk is offline
uk
Участник
 
14 / 10 (1) +
Регистрация: 06.05.2003
Адрес: Санкт-Петербург
Цитата:
Изначально опубликовано 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 не отработается) случится бяка и отчет больше никогда не запустится =)
Также можно установить подобный флажок не через кодъюнит, а используя поле какой-нибудь настроечной таблички (а можно и не настроечной...).
Но ведь свойство SingleInstance позволяет хранить значение переменной только для того же клиента, даже для одной сессии. То есть, при запуске другой сессии ReportIsRunning не будет True. Так что это свойство, к сожалению, тоже нельзя использовать. Похоже, единственный выход - при запуске отчета делать запись в некой таблице, при завершении отчета эту запись удалять. И не разрешать запускать отчет, пока эта запись существует. Но как-то это неправильно, мне кажется. Или ничего?

--------------------------------------------------------------------------------
Изначально опубликовано uk
Но при таком раскладе я не вижу возможности исключить параллельный запуск данного расчета.
--------------------------------------------------------------------------------
2 mazzy
Цитата:
А почему только данного? А у вас нет других расчетов, которые работают с этими же таблицами? Они же тоже могут что-то править. В промежутках между транзакциями. Я чего-то не понимаю?
Другие расчеты тоже что-то правят, но не те поля, которые правит расчет, о котором идет речь.
Мне трудно предсказать последствия параллельной работы этого расчета - поэтому я и хочу избежать подобной ситуации.
Старый 22.03.2004, 12:14   #15  
Svalik is offline
Svalik
Участник
 
20 / 10 (1) +
Регистрация: 10.09.2002
Адрес: Москва
Не пойму в чем проблема.
В любую таблицу (например в InventorySetup) добавляем поле
типа CrazyReportIsRunning boolean
В репорте в самом начале проверяем этот флажок. Если надо -
выставляем, модифаим, работаем. Делов-то на 2 минуты.
Или я чего-то не знаю?
Старый 22.03.2004, 17:12   #16  
uk is offline
uk
Участник
 
14 / 10 (1) +
Регистрация: 06.05.2003
Адрес: Санкт-Петербург
Вопрос в том, когда этот флажок снимать. Видимо, в OnPostReport.
Допустим, пользователь завершил отчет по Esc, не дожидаясь окончания. OnPostReport не отработал, флажок остался - отчет IsRunning. Больше никогда не запустится.
Старый 22.03.2004, 17:20   #17  
Svalik is offline
Svalik
Участник
 
20 / 10 (1) +
Регистрация: 10.09.2002
Адрес: Москва
точно... у него же в отчете коммиты понатыканы... вот ведь.;-0
Старый 22.03.2004, 19:47   #18  
Yuriy is offline
Yuriy
Участник
 
150 / 10 (1) +
Регистрация: 25.02.2003
Адрес: Москва
Коррекция себестоимости, если мне не изменяет память, запускается из пункта меню. Можно прописать на методе OnPush этого пункта меню код:

если есть галочка в некотором поле, то не запускать отчет, иначе:
поставить галочку, например, в таблице Location Setup (предварительно добавив туда поле)...
CLEAR(TestReport);
TestReport.RUNMODAL;

снять галочку в поле в таблице настроек.
Вот вроде и все.
__________________
Вот такие, брат, дела!
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Печать отчета из просмотра gennady NAV: Программирование 1 03.02.2006 08:03
Свойство KeepWithNext тела отчета! Yuriy NAV: Программирование 2 31.07.2003 15:09
Проблема с компиляцией отчёта RomariO NAV: Программирование 2 23.04.2003 11:21
[Attein 3.01]Запрет печати отчета из предварительно просмотра. Yoil NAV: Программирование 11 18.04.2003 16:36

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 12:50.