powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Массовое обновление данных в базе
25 сообщений из 74, страница 1 из 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
25 сообщений из 74, страница 1 из 3
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Массовое обновление данных в базе
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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