|
Инкремент
|
|||
---|---|---|---|
#18+
Прошу прощения за глупый вопрос, но, что-то я заблудился в трех соснах. Итак задача: есть набор объектов, по каждому объекту могут возникать события. Пользователь может перевести новое событие в состояние "обработано", а потом в состояние "закрыто". В база порядка сотни объектов. События возникают, ну скажем, раз в полчаса - час по каждому объекту. У каждого объекта может быть сколь угодно закрытых событий и не более 100 новых и обработанных. Теперь задача - требуется возвратить статус объекта. Пускай будет 0 - есть новые события, 1 - все события обработаны, но есть открытые, 2 - все события закрыты. Как я это реализовал - добавил в объекты два поля OPEN_CNT, REPORT_CNT. При появлении события вызываю Код: sql 1. 2. 3. 4.
при обработке Код: sql 1. 2. 3. 4. 5.
при закрытии REPORT_CNT = REPORT_CNT - 1 WHERE ID = :id[/SRC]Потом анализирую значения этих двух счетчиков и выдаю итоговый статус. Но мучает меня вопрос: а можно ли делать такие апдейты? Не нарвусь ли я в итоге на параллельный апдейт с двух потоков, когда все пойдет в разнос? Все это происходит на сервере. Т.к. количество объектов число переменное, то использовать генераторы не представляется возможным (или я не вижу как). Добавить статус в само событие а потом делать выборки по этому статусу не хочется, т.к. событий будет накапливаться много С уважением, Vasilisk ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 03:27 |
|
Инкремент
|
|||
---|---|---|---|
#18+
_Vasilisk_> Но мучает меня вопрос: а можно ли делать такие апдейты? Можно. > Не нарвусь ли я в итоге на параллельный апдейт с двух потоков, когда все пойдет в разнос? Нет. Особенно, если будешь это делать не в RC, а в снапшоте. Именно инкрментальные апдейты можно и нужно делать в RC, но если конкуренция невысока, то лично я бы предпочёл короткий снапшот. Впрочем, если ты имеешь в виду, что можно нарваться на ошибку (exception) при параллельном запросе - да, можно, но не вижу с этим проблем, БД и данные не будут повреждены, просто отлавливай эксепшн. > Добавить статус в само событие а потом делать выборки по этому > статусу не хочется, т.к. событий будет накапливаться много И правильно, это кривая архитектура независимо от количества. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 05:15 |
|
Инкремент
|
|||
---|---|---|---|
#18+
_Vasilisk_Теперь задача - требуется возвратить статус объекта. Одного объекта или всех сразу? Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 12:31 |
|
Инкремент
|
|||
---|---|---|---|
#18+
Гаджимурадов РустамВпрочем, если ты имеешь в виду, что можно нарваться на ошибку (exception) при параллельном запросеНет. Имелось в виду. именно целостность данных. Апдейты делаются в коротком RC. Конкуренции практически нет - один поток делает инкремент, второй - декремент. Спасибо за разъяснения Dimitry SibiryakovОдного объекта или всех сразу?Всех ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 13:46 |
|
Инкремент
|
|||
---|---|---|---|
#18+
_Vasilisk_> Имелось в виду. именно целостность данных. Данные не попортятся, но эксепшен теоретически возможен даже при низкой конкуренции, так что обработку ошибки и повтор операции всё-таки добавь. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 13:49 |
|
Инкремент
|
|||
---|---|---|---|
#18+
_Vasilisk_Всех На мой взгляд даже в этом случае для 100 объктов не стоит заморачиваться хранимыми агрегатами. Индекс на "объект,статус" в таблице событий и запрос Код: sql 1. 2. 3.
вернёт для каждого объекта статус "новый" если есть хоть одно новое событие, "обработанный" если новых событий нет, но есть незакрытые и "закрыто" во всех остальных случаях. Да, это вложенный цикл, но он будет работать всего в 3-4 раза медленнее, поскольку на каждую запись в таблице объектов будет одно индексное чтение таблицы статусов. Зато нет тормозов и конкуренции при изменении статусов. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 13:57 |
|
Инкремент
|
|||
---|---|---|---|
#18+
_Vasilisk_ В целом - оно так и есть. Но можешь в ходе конкуренции потерять статус объекта (станет за счет счетчика, к примеру, 3 или 4) Приведи задачу к двум регистрам. 1) Регистр остатков - это поля из таблицы объектов (ID, OPEN_CNT, REPORT_CNT). Для красоты и чоткости логики можно создать отдельную VIEW, но это это все уже слишком. 2) Регистр движений - таблица, отражающая движения статуса объектов (ID[OBJECTS], DATE_COMMIT, OPER_CNT, REPORT_CNT), в которую вставляй записи при возникновении события 3) а триггеры регистра движений пусть сами изменяют статус у объекта в регистре остатков. И самое главное - только триггеры могут менять значение в регистре остатков. То есть, нужно что-то поменять - мы добавляем соответствующую запись в регистре движений. Тогда стопудово получишь картину и историю изменения статуса объектов. ------------ З.Ы. система ограничений - на пространство жесткого диска клиента мы забиваем. условно считаем, что но бесконечно. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 16:03 |
|
Инкремент
|
|||
---|---|---|---|
#18+
PEAKTOP> Но можешь в ходе конкуренции потерять статус объекта PEAKTOP> (станет за счет счетчика, к примеру, 3 или 4) Ты бредишь. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 23:44 |
|
Инкремент
|
|||
---|---|---|---|
#18+
Гаджимурадов РустамТы бредишь. Да, конечно. Это только результат моего больного воображения. Мне - можно. У меня даже справка есть. Даю подсказу: одновременно стартуют минимум две (три, десять, ..., n) транзакции isc_tpb_read_committed isc_tpb_write isc_tpb_record_version isc_tpb_nowait ... |
|||
:
Нравится:
Не нравится:
|
|||
09.02.2013, 00:11 |
|
Инкремент
|
|||
---|---|---|---|
#18+
PEAKTOP> Даю подсказу: одновременно стартуют минимум две (три, десять, ..., n) транзакции Ты развивай мысль, развивай. У тебя уже и подсказка вон есть. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.02.2013, 00:25 |
|
Инкремент
|
|||
---|---|---|---|
#18+
Как правильно увеличить значение поля в хранимой процедуре? процедура простая, несколько входящих параметров и UPDATE OR INSERT: Код: sql 1.
Ошибка возле "MSG_COUNT + 1": Column unknown MSG_COUNT Неужели предварительно придётся считывать значение во временную переменную? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:02 |
|
Инкремент
|
|||
---|---|---|---|
#18+
X11, двоеточие забыл перед msg_count+1 ? да и перед username тоже. Брось, перепиши в понедельник. процедуру не вижу. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:15 |
|
Инкремент
|
|||
---|---|---|---|
#18+
X11Неужели предварительно придётся считывать значение во временную переменную? Или так или мозгом подумать: откуда старое значение возьмётся при INSERT. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:25 |
|
Инкремент
|
|||
---|---|---|---|
#18+
09.11.2018 15:15, kdv пишет: > двоеточие забыл перед msg_count+1 ? он хочет ПОЛЕ инкрементировать Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:25 |
|
Инкремент
|
|||
---|---|---|---|
#18+
X11, Боюсь, что если рассуждать логически, то чукча, который инсерт, он же не читатель, а только чисто писатель и у него на момент формирования запроса соответсвующего контекста, с текущими значениями полей просто нема. Потому здесь и VALUE + 1 тоже не прокатит. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:26 |
|
Инкремент
|
|||
---|---|---|---|
#18+
X11, используй merge Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:27 |
|
Инкремент
|
|||
---|---|---|---|
#18+
Симонов Денис, ой, пропустил FROM RDB$DATABASE Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:29 |
|
Инкремент
|
|||
---|---|---|---|
#18+
Vlad F, был бы в Firebird ROW VALUE CONSTRUCTOR этот merge выглядел бы покрасивше и не надо было к RDB$DATABASE обращаться ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:33 |
|
Инкремент
|
|||
---|---|---|---|
#18+
kdvдвоеточие забыл перед msg_count+1 ? да и перед username тоже. ок, с параметром username согласен, но MSG_COUNT - это ж не параметр ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:42 |
|
Инкремент
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovX11Неужели предварительно придётся считывать значение во временную переменную? Или так или мозгом подумать: откуда старое значение возьмётся при INSERT. а если есть default 0? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:43 |
|
Инкремент
|
|||
---|---|---|---|
#18+
Vlad FX11, Боюсь, что если рассуждать логически, то чукча, который инсерт, он же не читатель, а только чисто писатель и у него на момент формирования запроса соответсвующего контекста, с текущими значениями полей просто нема. Потому здесь и VALUE + 1 тоже не прокатит. Было бы здорово, если бы прокатило. При Insert можно было бы вставить NULL либо Default + 1. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:46 |
|
Инкремент
|
|||
---|---|---|---|
#18+
X11а если есть default 0 да по фигу какой там default. Чем тебе merge не катит? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:46 |
|
Инкремент
|
|||
---|---|---|---|
#18+
я не сказал ,что не катит просто монстр какой-то получился а если по производительности - это то же самое, что и предварительный select в переменную, то это даже будет более читабельный код, чем merge ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 15:57 |
|
Инкремент
|
|||
---|---|---|---|
#18+
X11, ну про читаемость и монструозность вопрос спорный. Запрос из 10 строчек не такой уж большой, тем более его можно сократить, но в этом случае надо будет одноимённые переменные дважды использовать, что внутри ХП не страшно Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2018, 16:18 |
|
|
start [/forum/topic.php?fid=40&msg=39730740&tid=1560915]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
155ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 12ms |
total: | 268ms |
0 / 0 |