![]() |
Модераторы: LSD |
![]() ![]() ![]() |
|
Royan |
|
|||
Dreamer ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1708 Регистрация: 14.9.2002 Где: Лондон Репутация: 1 Всего: 15 |
Условия: Таблица, из которой весьма интенсивно одновременно читают и пишут несколько приложений
Задача: Обеспечить синхронизацию состояния таблицы для нескольких независимых процессов работающих с ней одновременно Вопрос: Как это сделать? Трудность в том, что в один и тот же момент времени два процесса могут прочесть ID (SELECT не синхронизируется транзакциями), а следующим шагом попытаться провести INSERT, в результате чего один из процессов свалится с ORA-00001: unique constraint (XXX) violated Вопрос есть ли возможность в Oracle преодолеть сию проблему? Может как-то грамотно засинхронизировать SELECT? -------------------- Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь |
|||
|
||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 37 Всего: 161 |
Общего рецепта нет. Есть лишь частные. Сериализовать доступ по чтению можно лишь блокировками. Блокировки оракл устанавливает лишь при операции записи. Надо придумать чтото чтобы это чтото кудато записывать перед чтением, либо использовать dbms_lock дабы не плодить сущего без надобного. Из контекста я понял что у тебя что то вроде insert into tab(id) select nvl(max(id),0)+1 from tab; Рецепт - Lock table tab in exclusive mode перед выполнением этой операции. Это сообщение отредактировал(а) Zloxa - 2.2.2009, 14:43 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
Deniel_li |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 6.12.2007 Репутация: нет Всего: 1 |
если правильно понял, то проблема в этом
ORA-00001: unique constraint (XXX) violated а почему бы вместо чтения Id из таблицы не воспользоваться последовательностями? тем более, если по условию с таблицей активно работают.... Это сообщение отредактировал(а) Deniel_li - 2.2.2009, 17:08 |
|||
|
||||
Royan |
|
||||||
Dreamer ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1708 Регистрация: 14.9.2002 Где: Лондон Репутация: 1 Всего: 15 |
Поясню проблему. У меня код работает буквально так
Далее код на java if(SELECT чего то нашел, то есть запись существует) {
} else {
} Я так понял этот подход совковый и надо в таких случаях использовать MERGE. Вопрос к знатокам, а MERGE блокирует табличку на время своего выполнения? -------------------- Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь |
||||||
|
|||||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 37 Всего: 161 |
По чтению - нет. Но ситуацию разрулит. Первому селекту можно добавить for update. Это будет гарантироватЬ, что если запись есть, то она никуда не денется. Можно заменить конструкцию на:
Но, соответственно, запись может потеряться, если произойдет фиксация удаления между инсертом и аптдейтом -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
DimW |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1330 Регистрация: 24.2.2005 Где: Орёл Репутация: 23 Всего: 44 |
оракле не предусмотрен механизм блокирования таблицы при модификации данных. блокируется всегда только модифицируемая строка/строки в независимости от их количества. MERGE всего лишь гарантирует выполнение одним оператором insert-a или update-a. не забываем что даный механизм должен быть реализован для всех приложений ибо от ORA-00001 не отвертеться. |
|||
|
||||
DimW |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1330 Регистрация: 24.2.2005 Где: Орёл Репутация: 23 Всего: 44 |
||||
|
||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 37 Всего: 161 |
При интенсивном удалении из той же таблицы, при таком подходе шанс поймать ora-00001 лишь слегка минимизируется. В предложенном мной варианте, мы имеем некислый шанс потерять апдейт. Я так понял проблема как раз таки вызвана тем, что присутствует еще и удаляющая сессия, назначение и принцип работы которой не раскрыты автором. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
DimW |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1330 Регистрация: 24.2.2005 Где: Орёл Репутация: 23 Всего: 44 |
||||
|
||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 37 Всего: 161 |
ЗЫ Сорри вообще гоню.
Не понял я откуда у меня взялось убеждение, что есть еще и удаляющая сессия. -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
DimW |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1330 Регистрация: 24.2.2005 Где: Орёл Репутация: 23 Всего: 44 |
Zloxa, что то мне кажется механизм где присутствуем еще и удаление несколько надуман, сложно представить жизненную ситуацию когда это рельно бы использовалось (имеется ввиду в контексте последовательного доступа к записи). если задача именно такая, то dbms_lock по id в помошь. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Oracle" | |
|
Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Oracle | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |