Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
День добрый. Необходимо сделать выборку из связанных таблиц так, чтобы их целостность в выборке не была нарушена. Поясню: есть две таблицы А и Б, где Б содержит foreign key на А . Сначала сохраняем таблицу А и затем Б. Но пока мы сохраняли А - произошли изменения в Б и А и эти изменения в сохраненных значениях в А не попали, а в Б попали. Таким образом в сохраненных значениях в таблице Б появились значения и ссылки на А, которых еще нет в А. Можно ли сделать нечто такое - открыть транзакцию которая не блокирует таблицы(некий SNAPSHOT), сделать выборки по таблицам (их может быть много и они большие), и закрыть транзакцию. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.02.2009, 19:48 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Если изменения - это только пополнения таблиц и нежелательно извлекать набор уже связанных данных - навскидку можно просто одним запросом получить максимальные величины ключей таблиц, например просто select max(id) from xxx union select max(id) from yyy а потом просто сделать выборки не торопясь :) where id < value ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.02.2009, 22:46 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Добрый день. Dmitry Y.Поясню: есть две таблицы А и Б, где Б содержит foreign key на А . Сначала сохраняем таблицу А и затем Б. Но пока мы сохраняли А - произошли изменения в Б и А и эти изменения в сохраненных значениях в А не попали, а в Б попали. Таким образом в сохраненных значениях в таблице Б появились значения и ссылки на А, которых еще нет в А.Можете на конкретном примере пояснить, что вы имеете ввиду? А то не очень понятно, что значит "сохраняем таблицу". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2009, 12:51 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Судя по всему речь идет о получении моментального целостного (consistent) снимка базы. База находится в целостном состоянии, когда завершены все транзакции и новые еще не начались. Если обозначить состояния базы как Bi, а изменения как CHi, то процесс изменения состояния можно представить так: Код: plaintext 1. 2. Автора, видимо, интересуют все записи таблиц T1, T2,... в состояниях B0 или B5, то есть в тех состояних, когда данные целостны. Состояния B1,B2,B3,B4 не целостны, так как в базе есть незавершенные изменения. Как это можно сделать без блокировок - непонятно. Если автор не хочет делать блокировок, то проблема нарушения целостности возникнет даже для одной таблицы. Пока мы идем по таблице, то еще не считанные нами записи изменяются другими транзакциями и полученный снимок будет содержать записи привязанные к разным моментам времени. Типичный пример - оборотная ведомость. В результате такого чтения сумма оборотов по дебету не будет равна сумме оборотов по кредиту, что есть нехорошо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2009, 16:39 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Mark BarinsteinДобрый день. Можете на конкретном примере пояснить, что вы имеете ввиду? А то не очень понятно, что значит "сохраняем таблицу". Задача состоит в том, чтобы данные из системы DB2 реплицировать в другую не на DB2. Есть признаки по которым я могу выдернуть из таблицы изменения (включая удаления) от последней репликации. Но проблема всплывает тогда, когда в момент переноса идет работа операторов в исходной БД. Вообщем-то все работает за исключением случая, когда создается предок с существующей ссылкой в родителе, а затем добавляется новый родитель и он исправляется в созданном предке в момент переноса таблицы предка. (Такое бывает раз-два в месяц при реплике каждые 5 минут по 100 таблицам с 2-3 уровнями вложений) Все остальное отрабатывается без конфликтов. Если не вникать глубоко, мне фактически надо сделать выборку из всех таблиц по очереди - какбы заморозив базу для одной сессии, некий snapshot, тогда как для других сессий база работает штатно. Фактически это UNION ALL для всех таблиц, только учитывая что они все разные - и надо делать для каждой свои select-ы. Во. Можно так? Понаделать временных таблиц точной копией исходных. Потом: begin atomic insert into a1_temp (select * from table a1 where трампампам); insert into a2_temp (select * from table a2 where трампампам); insert into a3_temp (select * from table a3 where трампампам); ... end Потом выдрать из временных таблиц значения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2009, 02:38 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
шубин_дуТипичный пример - оборотная ведомость. В результате такого чтения сумма оборотов по дебету не будет равна сумме оборотов по кредиту, что есть нехорошо. Если проводка делается одной транзакцией (по дебиту и кредиту и чему угодно еще), то такого никогда не будет. Иначе это кривое программирование :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2009, 02:47 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Вам надо реплицировать не таблицы по отдельности а некий поток данных (аналог паттерна команда из GoF) из основной БД в другую. Сам поток команд хранится в таблице и обрабатываются эти команды в разнесенных базах одинаковым образом, например некой хранимой процедурой или триггером. Тогда обе БД будут синхронны (с неким лагом по времени) и все данные внутри таблиц будут логически целостны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2009, 13:21 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Dmitry Y.шубин_дуТипичный пример - оборотная ведомость. В результате такого чтения сумма оборотов по дебету не будет равна сумме оборотов по кредиту, что есть нехорошо. Если проводка делается одной транзакцией (по дебиту и кредиту и чему угодно еще), то такого никогда не будет. Иначе это кривое программирование :) Не проводка, а запрос. Никаких изменений, только чтение. И тем не менее будет. С самым что ни на есть правильным программированием. Ключевое слово "блокировка". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2009, 13:52 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Ggg_oldВам надо реплицировать не таблицы по отдельности а некий поток данных (аналог паттерна команда из GoF) из основной БД в другую. Сам поток команд хранится в таблице и обрабатываются эти команды в разнесенных базах одинаковым образом, например некой хранимой процедурой или триггером. Тогда обе БД будут синхронны (с неким лагом по времени) и все данные внутри таблиц будут логически целостны. Это сложно, и приведет в потере производительности бд. У нас реплика аналогичная lotus notes. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.02.2009, 22:11 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
шубин_дуDmitry Y.шубин_дуТипичный пример - оборотная ведомость. В результате такого чтения сумма оборотов по дебету не будет равна сумме оборотов по кредиту, что есть нехорошо. Если проводка делается одной транзакцией (по дебиту и кредиту и чему угодно еще), то такого никогда не будет. Иначе это кривое программирование :) Не проводка, а запрос. Никаких изменений, только чтение. И тем не менее будет. С самым что ни на есть правильным программированием. Ключевое слово "блокировка". Ключевое слово транзакция. Если бы выборка из таблиц приводила к блокировкам, бд невозможно было бы пользоваться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.02.2009, 22:17 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Dmitry Y.шубин_дуDmitry Y.шубин_дуТипичный пример - оборотная ведомость. В результате такого чтения сумма оборотов по дебету не будет равна сумме оборотов по кредиту, что есть нехорошо. Если проводка делается одной транзакцией (по дебиту и кредиту и чему угодно еще), то такого никогда не будет. Иначе это кривое программирование :) Не проводка, а запрос. Никаких изменений, только чтение. И тем не менее будет. С самым что ни на есть правильным программированием. Ключевое слово "блокировка". Ключевое слово транзакция. Если бы выборка из таблиц приводила к блокировкам, бд невозможно было бы пользоваться. И тем не менее. Откройте, пожалуйста, доку по DB2 и ознакомьтесь с тем как организуется изоляция транзакций. Выборка при определенных обстоятельстах приводит к блокировкам. Например, в вашем случае, когда нужен полный и целостный скан таблицы, select будет приводить к блокировкам. DB2 Version 9.5 for Linux, UNIX, and WindowsTuning Tuning Database Performance, Chapter 18. Application considerations, Isolation levels and performance. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 00:55 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Dmitry Y. шубин_ду Господа, не ссорьтесь! :-) С одной стороны, выборка, конечно , может накладывать и накладывает блокировки, но блокировки-то бывают разные в зависимости от уровня изоляции (напр, select ... with ur , select ...with cr) С другой стороны, если правильно написать транзакцию проводки, то она, во-первых, дождется окончания select-а, чтобы наложить свои блокировки, м во-вторых, не даст начаться новому select-у, пока сама не закончится. Что касается самого топика, то без блокировок, конечно, не обойтись, иначе так и будет кривизна раз в два месяца. Нужно только правильный уровень изрляции выбрать. Никакие временные таблицы не помогут, т к и они в предлагаемом варианте будут содержать "inconsistent data", ну , может, только реже будет встречаться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 11:01 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Перевод денег со счета на счет со стандартным уровнем изоляции CS. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. В исходном состоянии клиент имеет 2 счета. Счет 1 содержит 20 рублей, счет 2 80 рублей. Сессия 1 переводит 10 рублей со счета 2 на счет 1 Параллельно сессия 2 проверяет состояние счетов клиента Обе сессии имеют стандартный уровень изоляции CS (Cursor Stability) ========================================================= Session 1 --------- Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. --------- Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Session 1 --------- Код: plaintext 1. 2. --------- Код: plaintext 1. 2. 3. Session 1 --------- Код: plaintext 1. 2. 3. 4. Сессия 2 отвисла. Session 2 --------- Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Курсор показывет состояние счетов: счет 1 20 рублей, счет 2 70 рублей. Итого у клиента имеется 90 рублей. Куда пропали 10 рублей?! Сессия 2 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Теперь все на месте. Приведенные выше курсор показывает первую строку по состоянию до коммита в сессии 1, а вторую строку по состоянию после коммита. Его проблема в том, что он ждал запись для счета 2, чтобы наложить на нее "быструю" блокировку INK , а запись была заблокирована сессией 1. После коммита в сессии 1 запись освободилась, курсор пошел дальше и прочитал новое состояние записи для счета 2, в итоге получили состояние счетов клиента (20,70), которое в базе в целостном виде не существовало. Целостные состояния (20, 80) и (30, 70). Чтобы их получить надо правильно выбрать уровень изоляции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 11:52 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
ну так и я о том же. нужно правильный уровень изоляции выбирать. Я так думаю, если в приведенном примере для "транзакции" ( т е сессии 1) выбрать уровень изоляции повыше, то все нормально будет, несмотря на уровень CS для сессии 2. Хотя зуб не дам... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 12:48 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
begin atomic update saldo set amount = amount - 10 where account = 2; update saldo set amount = amount + 10 where account = 1; end А сделайте вот так :) И попробуйте выбрать из таблицы значения с нарушением целостности с любым уровнем изоляции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 14:08 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Dmitry Y. Во. Можно так? Понаделать временных таблиц точной копией исходных. Потом: begin atomic insert into a1_temp (select * from table a1 where трампампам); insert into a2_temp (select * from table a2 where трампампам); insert into a3_temp (select * from table a3 where трампампам); ... end Потом выдрать из временных таблиц значения. А это не поможет? select 1 as F1 from table a1 where трампампам1 union all select 1 as F2 from table a2 where трампампам2 union all select 1 as F3 from table a3 where трампампам3 with RR USE AND KEEP UPDATE LOCKS По идее как раз то, что хотите получится. Все записи, попадающие под условия выберутся и заблокируются от обновления. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 14:08 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
dronNNну так и я о том же. нужно правильный уровень изоляции выбирать. Я так думаю, если в приведенном примере для "транзакции" ( т е сессии 1) выбрать уровень изоляции повыше, то все нормально будет, несмотря на уровень CS для сессии 2. Хотя зуб не дам... Использовать CS для выборки страшно неудобно. Если выборка будет скажем минуту - это ж вся система подвиснет. Везде использовал в выборках UR. А где надо проводку единой операцией begin atoimic - end; Даже с выборкой внутри. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 14:14 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Dmitry Y.А сделайте вот так :) И попробуйте выбрать из таблицы значения с нарушением целостности с любым уровнем изоляции. А я бы не стал так делать все же. Конечно, поймать момент между выполнениями двух update-ов сложно, но не невозможно. Миллион раз пройдет, на миллион первый - получим ситуацию, описанную шубин_ду и никакой atomic не поможет. Транзакция гарантирует целостность записанных (измененных данных), но никак не гарантирует от того, что кто-то прочитает данные посредине транзакции. Для этого именно блокировки и придуманы. Т е нужно каким-то образом указывать уровень изоляции транзакции (или всего приложения) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 14:34 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
ARIST_A А это не поможет? select 1 as F1 from table a1 where трампампам1 union all select 1 as F2 from table a2 where трампампам2 union all select 1 as F3 from table a3 where трампампам3 with RR USE AND KEEP UPDATE LOCKS По идее как раз то, что хотите получится. Все записи, попадающие под условия выберутся и заблокируются от обновления. Низя ничего блочить. Это рабочая бд в которой делается в минуту до 1000 транзакций. Если я на минуту заблочу (а реплику надо делать раз 5 минут) меня подвесят за одно место. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 14:34 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Dmitry YНизя ничего блочить. Это рабочая бд в которой делается в минуту до 1000 транзакций. Если я на минуту заблочу (а реплику надо делать раз 5 минут) меня подвесят за одно место. ну если нельзя ничего блочить - то имеете, то что имеете и никто вам не поможет, думаю. С ARIST_A согласен - очень похоже, что так и надо. Кстати, какое средство для репликации сейчас используется? в db2 sql-репликации есть специальный параметр, чтобы только целые транзакции реплицировались. Если используется что-то другое, можно попробовать использовать db2 sql-репликацию в промежуточную базу. Если ресурсы есть, конечно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 15:00 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Ну тогда остается только select ... WITH RR USE AND KEEP UPDATE LOCKS DGTT from select, залоченный выше DGTT from select, залоченный выше commit а дальше делайте что хотите. Либо вводите служебную таблицу и навешивайте триггеры для регистрации изменений в таблицах, чтобы потом сделать временной срез. Но это будет работать только при упорядоченных ключах. Либо вводите время как колонку каждой таблицы, чтобы было видно когда модифицирована/добавлена запись. А дальше опять же временной срез. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 15:04 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Dmitry Y.begin atomic update saldo set amount = amount - 10 where account = 2; update saldo set amount = amount + 10 where account = 1; end А сделайте вот так :) И попробуйте выбрать из таблицы значения с нарушением целостности с любым уровнем изоляции. А что меняет atomic в описанном выше примере? Вторая сессия не сможет прочитать первую запись, пока первая сессия делает обновление второй записи? Сможет. Операция update выполняется не наносекунды, а микросекунды. А при неудачном стечении обстоятельств миллисекунды. Вполне достаточно, чтобы вторая сессия успела прочитать первую запись. А если параллельных сессий не 2, а 100, то вероятность плохого ответа будет больше. Ну и кроме того на практике очень частно бизнес-логика требует каких-то дополнительных операций между обновлениями, что приведет к временной "дырке" между обновлениями. Если вы пишете надежное приложение, то нельзя полагаться на то, что селект успеет "проскочить". Может успеет, а может нет. Если нет и неверный результат в сессии 2 стоит больших денег, то нужно применять правильный уровень изоляции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 15:13 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
ДокаThe BEGIN ... END statement gives the statements defined within the BEGIN and END keywords the status of a single statement. Т.е. все что находится внутри begin end - выполняется как _одна_ целая операция с одной точкой актуальности. И любая выборка выдаст значения либо со _всеми_ действиями произведенными внутри или без. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 15:26 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
dronNN Кстати, какое средство для репликации сейчас используется? Было разработано свое решение. Реплика дизайна бд и реплика данных бд. Поскольку мы используем Express-C то родная реплика данных Db2 нам недоступна. А реплики дизайна и нет вовсе в db2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 15:40 |
|
||
|
Выборка и БД без нарушения целостности
|
|||
|---|---|---|---|
|
#18+
Dmitry Y.ДокаThe BEGIN ... END statement gives the statements defined within the BEGIN and END keywords the status of a single statement. Т.е. все что находится внутри begin end - выполняется как _одна_ целая операция с одной точкой актуальности. И любая выборка выдаст значения либо со _всеми_ действиями произведенными внутри или без. begin atomic end означает только "ATOMIC indicates that, if an error occurs in the compound statement, all SQL statements in the compound statement will be rolled back, and any remaining SQL statements in the compound statement are not processed." и ничего больше. Про точку актуальности в доке ничего нет. Но практика критерий истинности. Тест на begin etomic end. Чтобы смоделировать задержку между двумя update внутри блока делаем еще 1 таблицу locker. Решение, наверное, не очень красивое поскольку, вероятно, в DB2 есть какая-нибудь стандартная функция имитирующая задержку. Код: plaintext 1. 2. 3. Вспомогательная сессия Код: plaintext 1. 2. Сессия 1 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Висит на операторе update locker. Сессия 2 Код: plaintext 1. 2. 3. Висит так как запись 2 в saldo заблокирована сессией 1. Вспомогательная сессия Код: plaintext 1. 2. Сессия 1 продолжает дальше Код: plaintext 1. 2. 3. 4. Сессия 2 продолжает дальше Сессия 2 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Повторяем Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Так что begin atomic не помог. Нет никакой точки актуальности. Сессия 2 берет первую запись потому что она свободна и ждет вторую запись, потому что она заблокирована. Когда запись освобождается сессия 2 берет то значение, которое туда была записано первой сессией. Поэтому получаем странный результат - первая запись от одного целостного состояния, а вторая от другого. Потому что уровень изоляции CS так работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2009, 17:02 |
|
||
|
|

start [/forum/topic.php?fid=43&fpage=84&tid=1603427]: |
0ms |
get settings: |
7ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
41ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
37ms |
get tp. blocked users: |
1ms |
| others: | 213ms |
| total: | 323ms |

| 0 / 0 |
