22.03.2012, 12:37 | #1 |
Постигающий
|
можно ли поймать остановку выполнения кода из дебаггера?
Всем здрасти!
задача такая выполняется программа: X++: { ttsBegin; //<наполнение таблицы> ttsCommit; ttsBegin; //<какой-то код, который должен выполняться за рамками предыдущей транзакции> //<--------------------------остановка выполнения из дебаггера (программист дернул стоп-кран) //<очистка таблицы> ttsCommit; } |
|
22.03.2012, 12:49 | #2 |
Участник
|
Не очень понял вопрос. Вы хотите в момент отладки программы влиять на ход её выполнения? На сколько я знаю через отладчик можно менять значения переменных базовых типов. Это наверное можно как-то использовать. Или ваш вопрос как-то связан с особенностями работы транзакций? Можно поподробнее что и для чего вы делаете?
|
|
22.03.2012, 12:53 | #3 |
Постигающий
|
Цитата:
Сообщение от S.Kuskov
Не очень понял вопрос. Вы хотите в момент отладки программы влиять на ход её выполнения? На сколько я знаю через отладчик можно менять значения переменных базовых типов. Это наверное можно как-то использовать. Или ваш вопрос как-то связан с особенностями работы транзакций? Можно поподробнее что и для чего вы делаете?
|
|
22.03.2012, 12:59 | #4 |
Участник
|
а вынести очистку таблицы за переделы этой транзакции нельзя, поместив очистку в отдельную транзакцию или в отдельный метод?
__________________
С уважением, Александр. |
|
22.03.2012, 13:01 | #5 |
Постигающий
|
Подробно о программе:
она выполняет определенную бизнес-логику. в первой транзакции мы заполняем таблицу лога. если в таблице лога есть запись, то другие пользователи не могут запустить эту бизнес-логику со своей машины, а чтобы данные о логе попадали в общую бд и сразу были "видны" всем юзерам, мы используем для заполнения лога отдельную транзакцию. Далее выполняется бизнес-логика. и по завершении мы должны почистить лог, чтобы другие пользователи получили возможность запускать нашу бизнес-логику |
|
22.03.2012, 13:02 | #6 |
Постигающий
|
|
|
22.03.2012, 13:03 | #7 |
Участник
|
Цитата:
Если проблема только в этом, то сделать это можно и не прерывая основную транзакцию в параллельном соединении. Последний раз редактировалось S.Kuskov; 22.03.2012 в 13:06. |
|
22.03.2012, 13:06 | #8 |
Постигающий
|
|
|
22.03.2012, 13:08 | #9 |
Участник
|
так по сути можно прервать работу первой транзакции, тогда не начнет выполняться и вторая. может лучше для данного лога использовать временную таблицу, класс struct или map, если у Вас лог динамичный и все равно чистится?
__________________
С уважением, Александр. |
|
22.03.2012, 13:10 | #10 |
Постигающий
|
как другие пользователи увидят содержимое тмп таблицы или map? данные о логе должны быть доступны всем и сразу и до того как начинает выполняться бизнеслогика. поэтому первая транзакция закрывается и открывается вторая
|
|
22.03.2012, 13:10 | #11 |
Участник
|
|
|
|
За это сообщение автора поблагодарили: Андрей К. (1), samolalex (1). |
22.03.2012, 13:14 | #12 |
Участник
|
да, упустил этот момент.
__________________
С уважением, Александр. |
|
22.03.2012, 13:18 | #13 |
Постигающий
|
то есть будет так:
X++: { ttsBegin; userConnection.ttsbegin(); //<заполняем лог> userConnection.ttscommit(); //<бизнес логика> //<----------------------------------если в этот момент происходит отключение электричества, // то все , что мы наинсертили в паралллельной транзакции откатится? //<очищаем лог> ttsCommit; } |
|
22.03.2012, 13:21 | #14 |
Участник
|
Тьфу. Только сейчас до меня дошло что именно вы пытаетесь реализовать. Блокировка запуска кода несколькими пользователями одновременно. Так?
Нет. Это делается по другому. Например, в той же таблице с логом оставьте одну запись. Эту запись внутри транзакции выбирайте для обновления и перед окончанием транзакции обновляйте. Тогда второй пользователь не сможет сделать тоже самое ровно до тех пор пока первый не освободит эту единственную запись. |
|
22.03.2012, 13:30 | #15 |
Постигающий
|
Цитата:
Сообщение от S.Kuskov
Тьфу. Только сейчас до меня дошло что именно вы пытаетесь реализовать. Блокировка запуска кода несколькими пользователями одновременно. Так?
Нет. Это делается по другому. Например, в той же таблице с логом оставьте одну запись. Эту запись внутри транзакции выбирайте для обновления и перед окончанием транзакции обновляйте. Тогда второй пользователь не сможет сделать тоже самое ровно до тех пор пока первый не освободит эту единственную запись. ну то есть вася пупкин запустил программу с параметром А, в лог попала строка со значением А. это значит что никто не может запускать программу с параметром А, пока вася пупкин не закончит и не очистит лог. пока что вижу лишь один выход - перед заполнением лога чистить его. но в связи с нюансами это тяжеловатая процедура будет... Последний раз редактировалось Андрей К.; 22.03.2012 в 13:33. |
|
22.03.2012, 13:46 | #16 |
Участник
|
Заведите в логе галку "заблокировано". Вместо заполнения и чистки лога снимайте и устанавливайте эту галку (делайте это внутри одной транзакции, как я описывал выше). Перед тем как начать транзакцию проверяйте есть ли в таблице строка с нужным параметром, если нет, то создавайте. На всякий случай задайте на таблице уникальный индекс, чтобы нельзя было создать две строчки с одним и тем же параметром.
|
|
22.03.2012, 14:54 | #17 |
Постигающий
|
Цитата:
Сообщение от S.Kuskov
Заведите в логе галку "заблокировано". Вместо заполнения и чистки лога снимайте и устанавливайте эту галку (делайте это внутри одной транзакции, как я описывал выше). Перед тем как начать транзакцию проверяйте есть ли в таблице строка с нужным параметром, если нет, то создавайте. На всякий случай задайте на таблице уникальный индекс, чтобы нельзя было создать две строчки с одним и тем же параметром.
|
|
22.03.2012, 15:11 | #18 |
Участник
|
Может посмотреть в сторону блокировки журналов? Там ведь при разноске тоже блокировка устанавливается.
Подробностей сейчас не вспомню - давненько смотрел, но общая идея 1. Заблокировать лог (не галочкой, а идентификатором сессии запустившего). 2. Открыть транзакцию, 3. выполнить логику 4. закрыть транзакцию, 5. снять блокировку А при проверке блокировки лога смотреть, а существует ли еще такая сессия. Если нет - блокировку считать недействительной. Тогда выключение электричества не помешает.
__________________
If it ain't broke, take it apart and find out why (с) |
|
22.03.2012, 15:26 | #19 |
Участник
|
Цитата:
Как принудительно создать блокировку? |
|
22.03.2012, 17:55 | #20 |
Участник
|
Может подойти класс Tread. Поскольку Вам все равно нужно чистить таблицу вне зависимости выполнилась ли бизнесс-логика или нет, то конструкцию можно организовать на примере следующего джоба :
X++: static void Job620(Args _args) { Thread bpt; // поток для бизнесс-процесса Thread clt; // поток для удаления таблицы bpt = new Thread(); clt = new Thread(); bpt.setInputParm(connull()); // передача параметров потоку для бизнесс-процесса // запуск bpt.run( classnum( TestClassThread),staticmethodstr(TestClassThread,BuisnessProcess)); bpt.waitUntilSignaled(); // ожидание завершения БП clt.setInputParm(connull()); / clt.run( classnum( TestClassThread ), staticmethodstr(TestClassThread,ClearTable)); // чистка clt.waitUntilSignaled(); // ожидание завершения чистки } X++: bpt.waitUntilSignaled(); X++: server static void BuisnessProcess(Thread t) { container con = t.getInputParm(); ; // выполнение бизнесс процесса // выполнение бизнесс процесса throw error('Ошибка'); } X++: server static void ClearTable(Thread t) { container con = t.getInputParm(); ; // очистка таблицы // очистка таблицы info('ClearTable'); }
__________________
-Ты в гномиков веришь? -Нет. -А они в тебя верят, смотри, не подведи их. Последний раз редактировалось Pustik; 22.03.2012 в 18:01. |
|
|
За это сообщение автора поблагодарили: Андрей К. (1). |
|
|