powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Массовое обновление данных в базе
74 сообщений из 74, показаны все 3 страниц
Массовое обновление данных в базе
    #39634918
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И снова здравствуйте.

Имеется три таблицы:

Код: plaintext
1.
2.
3.
4.
GROUPS  MEMBERS  RECORDS
id      id_grp   id_grp
name    id_user  value
...     value    ...
        ...

В один прекрасный момент требуется обновить поле value в таблицах MEMBERS и RECORDS для некоторого id_grp. При этом они должны быть обновлены все разом, в одной транзакции. Само обновление выглядит так: считывается текущее значение, обрабатывается, на его место записывается новое, кроме того эти поля в этих таблицах зависимы друг от друга. В силу непреодолимых технических причин процесс обновления может занимать до нескольких [десятков] минут и по его завершению не обновлённые записи становятся невалидными. Соответственно, если в этот момент какой-то пользователь изменит запись или добавит новую в таблицу RECORDS с этим же id_grp (читать можно), то процесс придётся начинать сначала.

Вопрос: как правильно реализовать такое обновление?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634921
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpВопрос: как правильно реализовать такое обновление?
Как вариант, можно сначала обновить "без обновления" (UPDATE RECORDS SET id_grp=id_grp WHERE...). И если это удалось - то отлуп получат уже другие транзакции, пытающиеся изменить эти записи. А эта при реальном обновлении по этой причине уже не отпадет.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634922
pastor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

select for update испробован?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634924
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpВопрос: как правильно реализовать такое обновление?

Транзакция уровня consistency. Возможно, даже с table preserve или явной блокировкой
таблицы от записи.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634934
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastoralekcvp,
select for update испробован?
Нет ещё, я вот и интересуюсь в каком направлении копать. Спасибо.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634935
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovТранзакция уровня consistency
Да это понятно. Это не убережет еще не измененные записи от изменения в других транзакциях.
pastorselect for update испробован?
Да, это вроде как раз для этого и придумано.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634936
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockalekcvpВопрос: как правильно реализовать такое обновление?
И если это удалось - то отлуп получат уже другие транзакции, пытающиеся изменить эти записи.
Это не помешает добавлению новых записей, как я понимаю?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634937
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
23.04.2018 17:14, pastor пишет:
> select for update испробован?

глупость
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634938
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpЭто не помешает добавлению новых записей, как я понимаю?
Нет, конечно не помешают. Но если должно помешать - то ни update, ни select for update не помогут.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634939
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockalekcvpЭто не помешает добавлению новых записей, как я понимаю?
Нет, конечно не помешают. Но если должно помешать - то ни update, ни select for update не помогут.
Ну в данный момент у меня тупо блокируются все три таблицы на изменение, но мне почему-то кажется что это неверный подход...
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634941
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
23.04.2018 17:29, alekcvp пишет:
> мне почему-то кажется что это неверный подход...

не парься.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634943
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отозвать грант на запись у простых смертных?

Навесить триггеры и проверять комбинацию спец юзера и некоего флага в некой табличке?

Было бы желание.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634945
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А запрос вида: update table set id = id where ... вызывает реально какие-нибудь изменения в базе или нет?

Ещё есть идея поставить в records триггер на добавление записей типа: select id from groups where id = new.id_grp with lock; и тогда добавление будет обламываться, если запись в groups уже заблокирована кем-то.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634946
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpНу в данный момент у меня тупо блокируются все три таблицы на изменение, но мне почему-то кажется что это неверный подход...
И как же тогда возможно
alekcvpесли в этот момент какой-то пользователь изменит запись или добавит новую в таблицу RECORDS
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634947
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpА запрос вида: update table set id = id where ... вызывает реально какие-нибудь изменения в базе или нет?смотря что подразумевается под "..."
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634948
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
23.04.2018 17:33, alekcvp пишет:
> Ещё есть идея

способов достичь нирваны через анус превеликое множество.
но нужно ли тебе это, при нормальной ориентации?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634949
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpА запрос вида: update table set id = id where ... вызывает реально какие-нибудь изменения в базе или нет?
Да. Добавляется версия записи. Как и при вызове SELECT FOR UPDATE WITH LOCK.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634950
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий23.04.2018 17:33, alekcvp пишет:
> Ещё есть идея

способов достичь нирваны через анус превеликое множество.
но нужно ли тебе это, при нормальной ориентации?

Ну, в идеале, мне хочется чтобы это обновление блокировало только записи связанные с обновляемой группой, позволяя нормально работать со всеми остальными...
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634953
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
23.04.2018 17:36, alekcvp пишет:
> Ну, в идеале, мне хочется чтобы это обновление блокировало только записи связанные с обновляемой группой, позволяя нормально работать со всеми остальными...

это не защитит тебя от Insert-а.
а триггер, мало того что он "транзакционно-зависим", только добавит времени выполнения.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39634955
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpв идеале, мне хочется чтобы это обновление блокировало только записи связанные с
обновляемой группой, позволяя нормально работать со всеми остальными...

Если "группа" определяется значением FK ключа, то перед работой с ней обнови master-запись.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635051
Mikle83
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,
Мало выходных данных:
акт вандализма разовый или периодически планируется?
Влиять на "вне субдшную" логику/алгоритмы есть возможность?
Падение производительности на время обновления критично?

Если Да, то логично для группы ввести флаг активен/нет.
Анализировать его на клиенте (?вьюхах/процедурах).

Тогда задача обновления не будет столь критичной.

Если нет, запрет реализуется через триггер: если на запись (группу?)
выставлен флаг - запрет обновления, вставки данных.

Основная цель: избежать длительной и большой транзакции.
Цена: производительность
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635143
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikle83alekcvp,
Мало выходных данных:
акт вандализма разовый или периодически планируется?
Влиять на "вне субдшную" логику/алгоритмы есть возможность?
Падение производительности на время обновления критично?

Если Да, то логично для группы ввести флаг активен/нет.
Анализировать его на клиенте (?вьюхах/процедурах).

Тогда задача обновления не будет столь критичной.

Если нет, запрет реализуется через триггер: если на запись (группу?)
выставлен флаг - запрет обновления, вставки данных.

Основная цель: избежать длительной и большой транзакции.
Цена: производительность

1. Разовый, но неоднократный, в смысле изредка возникает необходимость.
2. Есть, но не хотелось бы плодить сущности в виде дополнительных таблиц. К тому же это "псевдотрёхзвенка", т.е. приложение взаимодействует только с ХП.
3. Производительность вообще не критична, желательно чтобы во время обновления можно было получить доступ к незатронутым
обновлением записям.

Флаг - это хорошо, но если во время обновления приложение будет убито по какой-либо причине? Флаг в базе так и останется, группа станет недоступна и придётся лезть в базу "руками".
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635202
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpФлаг - это хорошо, но если во время обновления приложение будет убито по какой-либо причине? Флаг в базе так и останется
Флаг - это запись. Если ее удалось удалить обновить - значит, это "зависший" флаг (создввшая его транзакция его не удалила).
И как такое может быть, чтобы не было коммита, а флаг остался.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635273
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpФлаг - это хорошо, но если во время обновления приложение будет убито по какой-либо причине? Флаг в базе так и останется, группа станет недоступна и придётся лезть в базу "руками".В соседней теме Триггер на дисконнект. когда должен сработать? перетирали триггер на дисконнект, как раз для похожего случая. убиение приложения и сетевые обрывы закрывает вполне себе.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635287
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockalekcvpФлаг - это хорошо, но если во время обновления приложение будет убито по какой-либо причине? Флаг в базе так и останется
Флаг - это запись. Если ее удалось удалить обновить - значит, это "зависший" флаг (создввшая его транзакция его не удалила).
И как такое может быть, чтобы не было коммита, а флаг остался.
А если он создаётся внутри обновляющей транзакции, то другие пользователи его всё равно не увидят до тех пор пока транзакция не завершится - он бесполезен. Поэтому его надо создавать вне основной рабочей транзакции, потом делать commit и только потом начинать обновление данных.

В итоге сделал следующее:

1. Добавил в таблице групп поле grplock;
2. Когда пользователь запрашивает права на запись в эту группу, то это поле проверяется и если оно не null то он посылается;
3. Добавил ХП LOCK_GROUP(gid, locked), которая делает нехорошую вещь:
Код: plsql
1.
2.
3.
4.
  in autonomous transaction do
    update groups
      set grplock = case :locked when 1 then :uid else null end
      where group_id = :gid;

т.е. даже внутри транзакции она обновляет это поле и изменения видны всем. Если во время обновления данных произойдёт какой-либо exception, то она вызывается ещё раз с locked = 0, после чего транзакции делается rollback.

4. В дисконнект триггер добавил
Код: plsql
1.
2.
  if (uid is not null) then
    update groups set grplock = null where grplock = :uid;



P.S: Пишущая транзакция nowait.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635292
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpА если он создаётся внутри обновляющей транзакции, то другие пользователи его всё равно не увидят до тех пор пока транзакция не завершится - он бесполезен.Как раз увидят, если попытаются создать такую же запись. Или обновить существующую. UPDATE OR INSERT, например, упадет.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635293
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockalekcvpА если он создаётся внутри обновляющей транзакции, то другие пользователи его всё равно не увидят до тех пор пока транзакция не завершится - он бесполезен.Как раз увидят, если попытаются создать такую же запись. Или обновить существующую. UPDATE OR INSERT, например, упадет.
Ага, только мне нужно чтобы они и в другие таблицы не могли добавлять записи, ссылающиеся на эту.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635295
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpАга, только мне нужно чтобы они и в другие таблицы не могли добавлять записи, ссылающиеся на эту.Ну правильно!
Вначале добавляешь такой флаг, если получилось - делаешь все дальнейшие обновления по таблицам, если не получилось - полный отлуп.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635297
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpмне нужно чтобы они и в другие таблицы не могли добавлять записи, ссылающиеся на этуА, я понял. Ну сделай триггер в каждой такой таблице, который будет делать этот UPDATE OR INSERT флага.
Ужас какой-то, конечно :)
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635299
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockсделай триггер в каждой такой таблице, который будет делать этот UPDATE OR INSERT флагаУчти, в этом случае обновлять данные в этих таблицах сможет только одна транзакция. Смахивает на монопольное открытие dbf.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635306
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp1. Добавил в таблице групп поле grplock;Вынеси его в другую таблицу с контролем уникальности.
Смог добавить флаг - можно работать.
Не смог - занято.
Чтобы проверять зомби - добавь туда же CONNECTION ID того, кто добавил флаг.
Дальше рассказывать ?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635320
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladalekcvp1. Добавил в таблице групп поле grplock;Вынеси его в другую таблицу с контролем уникальности.
Смог добавить флаг - можно работать.
Не смог - занято.
Чтобы проверять зомби - добавь туда же CONNECTION ID того, кто добавил флаг.
Дальше рассказывать ?
1. Зачем в таблицу уникальности? Он же к ID группы привязан, на другие группы не влияет, а в этой его обновить не смогут, потому что чтобы обновить надо права получить, а эта функция проверяет наличие этого флага.
2. Ну так и сделал, и в триггере на дисконнект его прибиваю.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635322
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockYuRockсделай триггер в каждой такой таблице, который будет делать этот UPDATE OR INSERT флагаУчти, в этом случае обновлять данные в этих таблицах сможет только одна транзакция. Смахивает на монопольное открытие dbf.
Монопольное открытие можно и через lock_write сделать, мне это как раз и не нужно.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635327
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpЗачем в таблицу уникальности?Чтобы дважды не вставить один и тот же ID
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635345
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp2. Ну так и сделал, и в триггере на дисконнект его прибиваюТриггер на дисконнект может штатно не сработать.
А вот транзакцию обязательно рано или поздно отпустит, что даст возможность другой транзакции (пере)установить этот флаг (в "таблице уникальности").
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635423
Stalk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Использовать генератор для блокировки нежелательных изменений еще никто не предлагал?

Взвели генератор - проапдейтили - сняли генератор .
Для остальных проверка на триггере и Exception при необходимости.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635427
Котовасия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvphvladпропущено...
Вынеси его в другую таблицу с контролем уникальности.
Смог добавить флаг - можно работать.
Не смог - занято.
Чтобы проверять зомби - добавь туда же CONNECTION ID того, кто добавил флаг.
Дальше рассказывать ?
1. Зачем в таблицу уникальности? Он же к ID группы привязан, на другие группы не влияет, а в этой его обновить не смогут, потому что чтобы обновить надо права получить, а эта функция проверяет наличие этого флага.
2. Ну так и сделал, и в триггере на дисконнект его прибиваю.
Не надо проверять наличие флага.
Надо пытаться добавить флаг в табличку с констреинтом уникальности. Индексы живут вне контекста транзакций, поэтому ты гарантированно получишь отлуп при попытке добавить еще один флаг, даже если тебе запись с этим флагом не видна.
Заодно решаются "проблемы" с падением приложения: транзакция автоматом откатится, флаг снова можно будет добавлять.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635428
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalk,

очень плохое решение
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635431
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Котовасия,

ты предлагаешь удерживать тр-цию, вставившую флаг, на всё время "блокировки".
Не факт, что это приемлемо. Зависит от времени удержания "блокировки".


alekcvp,

надеюсь, ты понял, что значение флага == ID той группы записей, которую нужно "блокировать" ?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635442
Котовасия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladКотовасия,

ты предлагаешь удерживать тр-цию, вставившую флаг, на всё время "блокировки".
Не факт, что это приемлемо. Зависит от времени удержания "блокировки".
...
Ну так у ТС в исходном топике:
alekcvp...требуется обновить поле value в таблицах MEMBERS и RECORDS для некоторого id_grp. При этом они должны быть обновлены все разом, в одной транзакции ...

- какие тут сомнения?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635545
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladКотовасия,
ты предлагаешь удерживать тр-цию, вставившую флаг, на всё время "блокировки".
Не факт, что это приемлемо. Зависит от времени удержания "блокировки".
Вся операция, требующая блокировки, всё равно должна в одной транзакции выполняться, так что почему бы и нет?..

hvladalekcvp,
надеюсь, ты понял, что значение флага == ID той группы записей, которую нужно "блокировать" ?Ну это понятно, идея мне нравится. Но заводить для этого отдельную таблицу...
FireBird 3 поддерживает временные таблицы (которые в базу не пишутся), доступные одновременно всем подключениям?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635547
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpFireBird 3 поддерживает временные таблицы (которые в базу не пишутся), доступные одновременно всем подключениям?

нет конечно
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635574
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpНу, в идеале, мне хочется чтобы это обновление блокировало только записи связанные с обновляемой группой, позволяя нормально работать со всеми остальными...

Пройдет пару лет, система станет мощнее, и потребуется двумя "исполнителями" одновременно пересчитывать и апдейтить записи для двух разных групп.

Как бы ты не выбрал, надо заранее учитывать, что блокировок может быть несколько.

*возможно* проще всего на какой-нибудь из столбцов повесить CHECK CONTRAINT, что grp_id этой записи отсутствует в таблице блокировок WHERE LOCK_TABLE.ATTACHMENT <> CURRENT_CONNECTION. И триггером On Disconnect ее чистить не забывать.

Впрочем, это не убережёт от изменения самого grp_id если такое может случиться
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635577
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalk,

генератор не масштабируется на одновременное обновления 2 и более групп разными исполнителями
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635579
Котовасия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp...Но заводить для этого отдельную таблицу...
Прикинь, всего лишь создаешь табличку - и все, задача решена... :)
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635580
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpНу это понятно, идея мне нравится. Но заводить для этого отдельную таблицу...

Лучше завести ОДНУ лишнюю табличку и для блокировки добавлять ОДНУ строку в неё, чем переписывать ВСЕ строки целевой группы в твоей больше таблицы, даже если из всей группы ты потом только изменишь 1% записей.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635583
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockТриггер на дисконнект может штатно не сработать.

Может, хотя и не часто.
А вот триггер на коненкт сработает ;-)

Лайфхак из серии "чем общаги девочек отличаются от общаг мальчиков"
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635584
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
Код: plsql
1.
      set grplock = case :locked when 1 then :uid else null end


alekcvp
Код: plsql
1.
  if (uid is not null) then



кто есть uid ?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635585
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpFireBird 3 поддерживает временные таблицы (которые в базу не пишутся), доступные одновременно всем подключениям?

а если бы поддерживал?

ты не хочешь создавать ещё одну обычную таблицу (со списоком блокировок), но без хочешь создать ещё одну необычную (временную) таблицу?

а в чем разница?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635588
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpЕсли во время обновления данных произойдёт какой-либо exception, то она вызывается ещё раз с locked = 0, после чего транзакции делается rollback.



зачем?

Анекдот про два стакана на ночь у постели программиста?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635598
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpВся операция, требующая блокировки, всё равно должна в одной транзакции выполняться

Но сама блокировка может выполняться предварительно, в отдельной транзакции (если через флаги, в отдельной таблице или в отдельном столбце).

alekcvpЕсли в этот момент какой-то пользователь изменит запись или добавит новую в таблицу RECORDS с этим же id_grp (читать можно), то процесс придётся начинать сначала.

Вот это была мотивация или требование?

Что должно произойти, если пока мы рассчитываем группу №1 другое соединение пытается удалить или изменить или добавить строку в этой же группе?

Возможно, некоторые столбцы всё же можно изменять.
Возможно, изменяющего клиента нужно сразу послать.
Возможно, надо наоборот экстренно прервать процесс обновления. POST_EVENT и rollback, например.
Возможно, надо учитывать как давно или скуолько раз обновление уже откладывалось. Типа до получаса разрешаем так прерывать обновление, а потом начинаем отказывать изменяющим клиентам и принудительно доводим перересчёт до конца.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635650
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochalekcvpНу, в идеале, мне хочется чтобы это обновление блокировало только записи связанные с обновляемой группой, позволяя нормально работать со всеми остальными...
Пройдет пару лет, система станет мощнее, и потребуется двумя "исполнителями" одновременно пересчитывать и апдейтить записи для двух разных групп.
Не пройдёт, это "технический" процесс и он запускается не пользователями.
Да и приложение не корпоративного масштаба, так - внутренний софт на один отдел.

Завтра действительно попробую вариант с отдельной таблицей...
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635653
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochalekcvpНу это понятно, идея мне нравится. Но заводить для этого отдельную таблицу...

Лучше завести ОДНУ лишнюю табличку и для блокировки добавлять ОДНУ строку в неё, чем переписывать ВСЕ строки целевой группы
в твоей больше таблицы, даже если из всей группы ты потом только изменишь 1% записей.Сейчас я завёл ОДНО ПОЛЕ в таблице групп и делаю ДВУКРАТНУЮ запись в него на каждый процесс. А в варианте с отдельной таблицей, в неё будут записи (попытки записей) при КАЖДОМ изменении данных в ТРЁХ таблицах. Плюс в моём варианте [если возникнет необходимость] можно проверить блокировку даже из read_commited транзакции и не дать прочитать данные из обновляемой группы. В случае отдельной таблицы с попыткой записи - так не получится.
Ariochкто есть uid ?ID пользователя в таблице пользователей в базе. Т.е. поставить блокировку может кто угодно из тех кто имеет право писать в эти таблицы, а снять - только тот кто поставил. Ну и при дисконнекте по этому значению снимаются блокировки.
AriochalekcvpFireBird 3 поддерживает временные таблицы (которые в базу не пишутся), доступные одновременно всем подключениям?

а если бы поддерживал?

ты не хочешь создавать ещё одну обычную таблицу (со списоком блокировок), но без хочешь создать ещё одну необычную (временную) таблицу?

а в чем разница?В том, что при [аварийном] выключении сервера и при backup/restore не надо париться об этой таблице.
AriochalekcvpЕсли во время обновления данных произойдёт какой-либо exception, то она вызывается ещё раз с locked = 0, после чего транзакции делается rollback.



зачем?

Анекдот про два стакана на ночь у постели программиста?Я же показал - там внутри автономная транзакция, которая в любом случае снимает блокировку, а rollback основной транзакции отменяет изменения, которые уже успел сделать "вывалившийся" процесс.
AriochalekcvpВся операция, требующая блокировки, всё равно должна в одной транзакции выполняться
Но сама блокировка может выполняться предварительно, в отдельной транзакции (если через флаги, в отдельной таблице или в отдельном столбце). Может и так. Но мне проще всё "завернуть" в одну транзакцию.
AriochalekcvpЕсли в этот момент какой-то пользователь изменит запись или добавит новую в таблицу RECORDS с этим же id_grp (читать можно), то процесс придётся начинать сначала.
Вот это была мотивация или требование?
Что должно произойти, если пока мы рассчитываем группу №1 другое соединение пытается удалить или изменить или добавить строку в этой же группе?Ну представьте что там в записях электронные подписи, а в мемберсах - ключи для проверки. Что будет, если при смене этих подписей, кто-то добавит ещё одну запись, подписанную старым ключём (который считывается непосредственно перед подписью)? Если же обновлять сначала ключ, а потом подписи (в разных транзакциях), то кто-то в этот момент может попытаться проверить старую подпись новым ключём и будет облом.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635655
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

а что, старый и новый ключ не могут перекрываться по датам? Так ведь и происходит. я получаю новый ключ заранее, до окончания старого.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635659
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpСейчас я завёл ОДНО ПОЛЕ в таблице групп и делаю ДВУКРАТНУЮ запись в него на каждый процесс. А в варианте с отдельной таблицей, в неё будут записи (попытки записей) при КАЖДОМ изменении данных в ТРЁХ таблицах.Ну и зря.
Так тебе нужно обновлять миллион записей (реальных данных, с возможно еще какими-то триггерами, индексами) два раза по неизвестно какому условию.
А в случае таблицы локов - один раз, и еще миллион раз - обновлять одну запись с одним полем по ключу в короткой таблице. Что намного быстрее.
К тому же, твой вариант поможет только при обновлении данных, а таблицу локов можно использовать, если нужно, и для insert/delete.
alekcvpПлюс в моём варианте [если возникнет необходимость] можно проверить блокировку даже из read_commited транзакции и не дать прочитать данные из обновляемой группы. В случае отдельной таблицы с попыткой записи - так не получится.Транзакция любого типа может прочитать только закоммиченные данные. Так у тебя одна транзакция, или две? Или ты после первого update делаешь CommitRetaining?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635662
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpID пользователя в таблице пользователей в базе. Т.е. поставить блокировку может кто угодно из тех кто имеет право писать в эти таблицы, а снять - только тот кто поставил. Ну и при дисконнекте по этому значению снимаются блокировки.

а если клиент отвалился без отрабатывания триггера?

как, например, любому другому клиенту в триггере on connect определить, что пользователя Х остались бесхозные блокировки и снять их ?

Also, если расчёты идут так долго, то как часто клиент общается с сервером?
1. рассчитывает строку, записывает её в сервер (update), рассчитывает следующую, записывает, в конце - commit
2. долго рассчитывает все строки, потом все сразу сливает на сервер и commit, во время самих рассчетов с сервером не общается

alekcvpВ том, что при [аварийном] выключении сервера и при backup/restore не надо париться об этой таблице.

On connect триггер, зачищающий блокировки, IMHO все равно желателен.

alekcvpМожет и так. Но мне проще всё "завернуть" в одну транзакцию.

у тебя автономные транзакции летают - это уже едва ли "в одну"

alekcvpавтономная транзакция, которая в любом случае снимает блокировку

> Because the autonomous transaction is completely independent of its parent, care must be taken to avoid deadlocks.

В официальных примерах они используются только, чтобы добавлять записи в лог-таблицы.
У меня сильные сомнения, что есть какие-то гарантии по синхронизации.
Т.е. я не вижу принципиальной невозможности такой последовательности:
1. запускается транзакция на установку блокировки, но почему-либо притормаживается. Sweep пошёл тяжелый, или встала ждёт строку, модифицированную незакомиченной другой транзакцией
2. выполняются изменение данных и запускается автономка для снятия лока
3. 2-я автономка завершается, лок снят
4. 1-я автономка "отмерзает" завершается, лок выставлен

Я бы очень подумал, прежде чем с блокировками работать асинхронными средствами.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635664
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpМожет и так. Но мне проще всё "завернуть" в одну транзакцию.

дело не в том, что проще, а в том какого конкретно детерминированного поведения ты хочешь джобиться, в случае конфликта - 21365634 !!!

Вот тебе ещё на вскидку асинхронный сценарий.

1. ты из соединения 1 начал редактировать записи по группе 1,
2. начинает создаваться автономка №1 для выставления лока
3. пересчитывается и изменяется одна строка данных по группе 1
4. ты из соединения 2 редактируешь САМУ ГРУППУ 1, меняешь ей название например, но еще не коммитишь
5. автономка №1 начинает исполняться, обнаруживает, что запись группы была изменена из соединения 2 и по конфликту умирает с роллбаком.
6. соединение 2 коммитит переименование группы
7. пересчитывается и изменяется 2-я строка данных по группе 1
8. пересчитывается и изменяется 3-я строка данных по группе 1

....и т.д., изменения данных пошли, а лок не выставлен.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635666
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpНу представьте что там в записях электронные подписи, а в мемберсах - ключи для проверки.

я не хочу представлять и гадать, я хочу чтобы вы чётко сформулировали как в такой ситуации должна правильно вести себя ваша система. Какие варианты ее поведения желательны, какие нежелательны, но допустимы, и какие недопустимы категорически.

после того, как вы сформулируете четко поведение, "дизайн", можно обсуждать как такую "архитектуру" лучше закодировать.

но кодировать неизвестное несформулированное поведение - это с ненулевой вероятностью получить программу качества GIGO
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635668
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockТак тебе нужно обновлять миллион записей

нет, не так.

он добавил столбец - НЕ В ТАБЛИЦУ ДАННЫХ, а в отдельные "справочник групп"

"миллионы записей" он меняет в таблицах MEMBERS и RECORDS
а "выставляет флаг" в таблице GROUPS

во всяком случае я так его понял

PS. "обновлять два раза" возможно не так уж и плохо, если обновляются ВСЕ строки конкретной группы. Во всяком случае это не хуже, чем SELECT fOR UPDATE
Вот если бы он обновлял для блокировки миллион строк ,а потом реально вносил изменения данных в тысячу из них - тогда да, жуткий перерасход записей. Но если обновление тотальное - то двукратное или даже трекратное умножение записей вполне могло бы быть терпимым
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635669
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockalekcvpСейчас я завёл ОДНО ПОЛЕ в таблице групп и делаю ДВУКРАТНУЮ запись в него на каждый процесс. А в варианте с отдельной таблицей, в неё будут записи (попытки записей) при КАЖДОМ изменении данных в ТРЁХ таблицах.Ну и зря.
Так тебе нужно обновлять миллион записей (реальных данных, с возможно еще какими-то триггерами, индексами) два разаО, я недочитал.
Раз ты только "таблицу групп" дважды обновляешь - значит, это изменение "на клиенте" в логике. Значит, раз этого достаточно, можно и запись в таблицу локов один раз делать, а не в триггерах. Впрочем, это не важно, раз достаточно.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635670
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochнет, не так.

он добавил столбец - НЕ В ТАБЛИЦУ ДАННЫХ, а в отдельные "справочник групп"Да, я уже сам заметил.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635671
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

ну он просто объединил таблицу локов и таблицу-справочник групп воедино

если она не слишком широкая и сама по себе не часто меняется, то и нехай себе
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635672
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.....только нахрена же автономки тут.

Блокировки всегда делаются, чтобы принудительно и гарантировано сериализовать(синхронизировать) принципиально асинхронные (параллельные, хаотические по времени начала) операции.

А он пытается одни асинхронные операции сериализовать другими асинхронными.

Ну в большинстве случаев это сработает, конечно, не вопрос.
Всё таки БД на диске - не многоядерный процессор.
Но изредка гейзенбаги скорее всего будут случаться.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635674
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochВот тебе ещё на вскидку асинхронный сценарий.Я правильно тебя понял, что в твоём "асинхронном сценарии" основная и автономные тр-ции выполняются параллельно ?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635686
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvalekcvp,
а что, старый и новый ключ не могут перекрываться по датам? Так ведь и происходит. я получаю новый ключ заранее, до окончания старого.Это был пример для понимания, а не реальная ситуация. По факту там цифровые конверты - ключи в members и сами данные в records. Процесс обновления вызывается когда у кого-то отзывается доступ к группе, для смены ключей.
YuRockalekcvpПлюс в моём варианте [если возникнет необходимость] можно проверить блокировку даже из read_commited транзакции и не дать прочитать данные из обновляемой группы. В случае отдельной таблицы с попыткой записи - так не получится.Транзакция любого типа может прочитать только закоммиченные данные. Так у тебя одна транзакция, или две? Или ты после первого update делаешь CommitRetaining? У меня две транзакции. И проверить значение lock-поля в таблице групп я могу и из читающей, а чтобы попробовать что-то записать в отдельную таблицу и узнать получится или нет - мне придётся обязательно стартовать и пишущую.
AriochalekcvpID пользователя в таблице пользователей в базе. Т.е. поставить блокировку может кто угодно из тех кто имеет право писать в эти таблицы, а снять - только тот кто поставил. Ну и при дисконнекте по этому значению снимаются блокировки.а если клиент отвалился без отрабатывания триггера?Пока думаю над этим, но возможно заставлю ту процедуру, которая проверяет его наличие, проверять (опять же при состоянии locked = 1) так же наличие активной сессии заблокированного пользователя. Ну или перейду на вариант с отдельной таблицей - у обоих вариантов есть свои плюсы и минусы.
AriochAlso, если расчёты идут так долго, то как часто клиент общается с сервером?Хм, мне казалось что я написал: считывает строку, обрабатывает (~10 секунд), запихивает назад.
AriochalekcvpМожет и так. Но мне проще всё "завернуть" в одну транзакцию.
у тебя автономные транзакции летают - это уже едва ли "в одну" В одну с точки зрения приложения, что там в базе происходит - приложению знать не обязательно.
AriochЯ бы очень подумал, прежде чем с блокировками работать асинхронными средствами.Там же написано что автономная транзакция наследует параметры "родительской", родительская - nowait, т.е. либо обновила сразу, либо вывалилась с ошибкой. Или я как-то не так понимаю механизм nowait-транзакций (тоже вариант)?
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635953
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladЯ правильно тебя понял, что в твоём "асинхронном сценарии" основная и автономные тр-ции выполняются параллельно ?

могут выполняться параллельно.

в доках не указаны никакие гарантии синхронизации, стало быть это деталь реализации и сервер может делать так, как ему будет удобнее. В зависимости от содержимого базы ,настроек, версии сервера и фазы луны.

закладываться на то, что не имеет никаких гарантий и может при любом изменении данных или версий рассыпаться, да еще "в многопотоке" с его трудностями воспроизводимой диагностики - я бы не стал.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39635957
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpТам же написано что автономная транзакция наследует параметры "родительской"

там во-первых НЕ написано, что родительская транзакция встанет торчком и будет ждать окончания автономки.

Она запустит процесс создания и выполнения автономки, но когда та закончится и закоммититься - детали реализации.
Для ведения логов это подходит, если у тебя запись в лог внесется на несколько секунд позже, чем данные, не важно, лишь бы внеслась. Для синхронизации многопотока - на мой взгляд это раскладывание граблей.

И во вторых там НЕ написано, что родительская транзакция проверит результат автономки.
Я в твоем описании не заметил, что если 1-я автономка отвалится и не сможет выставить лок - то дальше процесс остановится.

Поэтому на мой вкус - лучше честно-примитивно делать две транзакции.

а) выставление лока, commit. Теперь приложение точно знает, что лок выставлен. Или что была ошибка.
б) изменение данных и снятие лока, commit;

в) и вообще, тогда ЛЮБЫЕ изменения данных, разумеется, должны делаться через локи. Не только большой-перерасчёт, но и любые. Чтобы не было картинки

1) соединение 1 хочет внести небольшие изменения в несколько строк данных по группе 1. Оно открывает транзакцию (RC? snapshot?), проверяет что лока нет (массовый перерасчет не идёт) и начинает изменять свои пару сотен строчек.
2) соединение 2 хочет начать массовый перерасчет и выставляет лок
3) соединение 1 продолжает изменять данные, потому что лок проверялся раньше и тогда его не было
4) соединение 2 тоже изменяет данные, но поскольку рассчёты большие и массивные - делает это медлено.

.....а дальше кто первый закоммитится, скорее всего 1-е.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39636015
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochhvladЯ правильно тебя понял, что в твоём "асинхронном сценарии" основная и автономные тр-ции выполняются параллельно ?

могут выполняться параллельно.

в доках не указаны никакие гарантии синхронизацииВ документации не обязаны описывать чьи-то фантазии.

Раз и навсегда - автономные тр-ции выполняются в том же логическом потоке управления, что и весь остальной код пользователя.
Если вдруг когда то появится *внутренняя* параллельность при выполнения запросов, то код пользователя никак об этом не узнает.
Разве что косвенно, по статистике\плану.
Но с точки зрения пользователя - это один логический поток управления. Без спецэффектов.

Ещё раз: тр-ция не является самостоятельным элементом выполнения кода.
Это просто характеристика текущего окружения, она не может "выполнять" запросы.
Это скорее контекст выполнения, а не само выполнение.

PS Выдыхай уже
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39636028
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochalekcvpТам же написано что автономная транзакция наследует параметры "родительской"
там во-первых НЕ написано, что родительская транзакция встанет торчком и будет ждать окончания автономки.

Это логически ожидаемо. Иначе можно сказать что нельзя писать хранимки с таким кодом:
Код: plsql
1.
2.
select phone from table where user_id = id into :phone;
insert into phonebook (phone, name) values (:phone, :name); 

Т.к. никто не гарантирует, что на момент insert'a select уже выполнится.
Что звучит как полный бред.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39636111
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpнельзя писать хранимки, Т.к. никто не гарантирует

FB documentationThe body of a PSQL module is a block of statements that run in a logical sequence, like a program.

Это во первых. А во вторых, твой стейтмент выполнился - автономная транзакция запущена. Остальное - детали реализации.


hvladВ документации не обязаны описывать чьи-то фантазии.

да вообще никто никому ничего не обязан.
и завязывать критический код на никому не обещанные детали реализации конечно же можно.
а если потом реализация будет оптимизирована - "так это, пойми, потом".


В общем, просто делаем на этом форуме поиск фразы "не обещал", читаем, потом думаем кто будет искать гейзенбаги в многопоточном коде лет через несколько, и выбираем.
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39636123
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

у тебя явная неспособность оценить уровень собственных фантазмов :)
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39636144
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochalekcvpнельзя писать хранимки, Т.к. никто не гарантирует
FB documentationThe body of a PSQL module is a block of statements that run in a logical sequence, like a program.
Это во первых. А во вторых, твой стейтмент выполнился - автономная транзакция запущена. Остальное - детали реализации.

Именно. "block of statements that run in a logical sequence". Т.е. в любой точке хранимки я могу быть уверен, что весь предыдущий код (с учётом ветвлений) уже выполнился, вне зависимости от того в автономной он транзакции или нет. Или с циклами for такая же фигня - он запустился на исполнение, а когда закончится - никто не знает, хранимка дальше пошла?.. :)
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39636282
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это уже не трава пошла...
...
Рейтинг: 0 / 0
Массовое обновление данных в базе
    #39636391
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишкаЭто уже не трава пошла...Сначала ее заваривали и пили, потом решали покурить, а когда начали вливать внутривенно пошел окончательный трэш.
...
Рейтинг: 0 / 0
74 сообщений из 74, показаны все 3 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Массовое обновление данных в базе
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]