Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> INSERT; UPDATE; SELECT; COMMIT; Есть ли race condition в моей проге? 
:(
    Опции темы
leniviy
Дата 29.1.2013, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



Есть многопоточная прога, которая работает с ораклом и считает интернет трафик юзера.
Инфа о трафике приходит маленькими кусочками в случайный поток.
Входная структура:
Код

user_id
day
volume

На одного юзера и день кусок трафика может прийти в разные потоки.
Задача: если сумма traffic превышает 30кб в день, надо создать выполнить определенное действие. Единожды.
В памяти хранить нельзя, их слишком много, поэтому создал таблицу с теми же полями, что в структуре:
Код

CREATE TABLE DAILYFLAT (
  MS_ID    NUMBER(15) NOT NULL,
  DAY    DATE NOT NULL,
  VOLUME_TODAY    NUMBER(15) NOT NULL
  , CONSTRAINT PK_DAILYFLAT PRIMARY KEY ( MS_ID , DAY )
);


Программа работает так:
Код

freevol = 30000;
insert into DAILYFLAT values ( :ms_id , :day, :volume );
if (sqlcode == DB_DUPLICATE_KEYINDEX) {
  update DAILYFLAT set VOLUME_TODAY = VOLUME_TODAY + :volume where ms_id  = :ms_id and day = :day;
  select VOLUME_TODAY into :newvolume from DAILYFLAT where ms_id  = :ms_id and day = :day;
  if (newvolume > freevol && volume <= freevol) { ... }
} else {
  if (volume > freevol) { ... }
}


Я считаю, что в этой схеме нет ошибок, но не уверен. Я раньше так не делал.


Это сообщение отредактировал(а) leniviy - 29.1.2013, 10:40
PM MAIL   Вверх
Zloxa
Дата 29.1.2013, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Удаляться данные из табилцы могут?
Если да, надо анализировать rowcount апдейта и возвращаться на insert, если он 0.

Селект тут можно опустить, если инструментарий позволяет получить returning апдейта.

Если в пределах транзакции ты добавляешь/обновляешь несколько записей, думай о дедлоках.

наверное ошибка здесь
Цитата(leniviy @  29.1.2013,  11:39 Найти цитируемый пост)
volume <= freevol

т.к. volume, по сути это дельта, мне кажется надо newvolume - volume сравнивать с freevol

Это сообщение отредактировал(а) Zloxa - 29.1.2013, 11:54


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Zloxa
Дата 29.1.2013, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



и... на сколько я понимаю суть, вероятность апдейта у нас куда выше вероятности инсерта, потому, наверное, лучше пробовать сразу апдейтить, если rowcount = 0, переходить на insert
Код

begin
  loop
    update table set val = val + :val 
      where...
      returning val into :new_val;
    if sql%rowcount = 1
    then
      exit;-- exit loop
    else
      begin
        insert into table values (...);
        :new_val := :val;  
        exit;-- exit loop
      exception
        when dup_val_on_index then null;
      end;
    end if;
  end loop;
  if :new_val > :freevol
    and :new_val-:val <= :freevol
  then
    ..
  end if;
end;


Это сообщение отредактировал(а) Zloxa - 29.1.2013, 12:16


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
leniviy
Дата 29.1.2013, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



Цитата(Zloxa @  29.1.2013,  11:50 Найти цитируемый пост)
Удаляться данные из табилцы могут?

удаляются через два дня

Цитата(Zloxa @  29.1.2013,  11:50 Найти цитируемый пост)

Если в пределах транзакции ты добавляешь/обновляешь несколько записей, думай о дедлоках.

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

Цитата(Zloxa @  29.1.2013,  11:50 Найти цитируемый пост)

наверное ошибка здесь
Цитата(leniviy @  29.1.2013,  11:39 Найти цитируемый пост)
volume <= freevol

т.к. volume, по сути это дельта, мне кажется надо newvolume - volume сравнивать с freevol

да, уже сам нашел.
PM MAIL   Вверх
Zloxa
Дата 29.1.2013, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(leniviy @  29.1.2013,  13:20 Найти цитируемый пост)
если кусок трафика начался вчера, а закончился сегодня.

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


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.0730 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.