Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Insert FOR UPDATE / 25 сообщений из 30, страница 1 из 2
05.10.2016, 09:46
    #39320736
Insert FOR UPDATE
Всем привет!
Есть таблица test (id number,value varchar2). Id присваиваются при инсерте триггером и сиквенсом.

Хотел написать процедуру которая добавляет еще одну строчку к таблице:

begin
insert into test05 (value) (select max(id)||'a' from test05);
end;

Но хочется чтобы это происходило с применением "последовательности сессий", т.е. с применением FOR UPDATE.
Написал это:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
declare 
    cursor C is
    select t.id,t.value
      from test05 t
     FOR UPDATE OF t.id; 
begin
  FOR rec in C loop
   insert into test05 (value) (select max(rec.id)||'a' from test05);
  end loop; 
  commit;  
end;


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

Прошу помочь разобраться,
Большое спасибо
...
Рейтинг: 0 / 0
05.10.2016, 09:51
    #39320740
Не понятно
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьумен,

Может все-таки сначала цель скажешь? Чего добиться-то хочешь в итоге?
...
Рейтинг: 0 / 0
05.10.2016, 09:53
    #39320742
Viewer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменВообще у меня очень плохое понимание что есть курсор...
Прошу помочь разобраться
У вас очень плохое понимание, что тfкое цикл (неважно, что по курсору) - попробуйте начать с этого - что такое цикл и почему "оно делает этот инсерт ровно столько раз, сколько в данный момент строчек в таблице."
...
Рейтинг: 0 / 0
05.10.2016, 09:55
    #39320743
Viewer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменНо хочется чтобы это происходило с применением "последовательности сессий", т.е. с применением FOR UPDATE.
Расшифруйте пожалуйста, что вы хотели этим сказать?
...
Рейтинг: 0 / 0
05.10.2016, 09:57
    #39320745
Insert FOR UPDATE
Не понятно,
хочу чтобы при срабатывании процедуры добавлялась в таблицу одна строчка. И если, например, процедуру запустят почти одновременно два человека, то один из них должен ждать второго, чтобы не получить в таблице двух строчек с одинаковым value, но разными id.
...
Рейтинг: 0 / 0
05.10.2016, 09:58
    #39320747
Viewer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
..а. .. понял сбило с толка вырфжение "последовательности сессий" , которое относится, как первоначално показалось, не к сессиям, а, на самом деле, к последовательности..
...
Рейтинг: 0 / 0
05.10.2016, 10:01
    #39320748
Не понятно
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменНе понятно,
хочу чтобы при срабатывании процедуры добавлялась в таблицу одна строчка. И если, например, процедуру запустят почти одновременно два человека, то один из них должен ждать второго, чтобы не получить в таблице двух строчек с одинаковым value, но разными id.
Нужно именно ЖДАТЬ? или просто нужно разные value для разных строчек? Типа еще один уникальный ключ в дополнение к id?
...
Рейтинг: 0 / 0
05.10.2016, 10:01
    #39320749
Viewer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
хм.. неправильно понял..
А чем вам сиквенс не угодил, зачем вам велосипед?
...
Рейтинг: 0 / 0
05.10.2016, 10:05
    #39320754
Zloxa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьумен,

lock table test05 in exclusive mode
...
Рейтинг: 0 / 0
05.10.2016, 10:08
    #39320756
Viewer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменхочу чтобы при срабатывании процедуры добавлялась в таблицу одна строчка. И если, например, процедуру запустят почти одновременно два человека, то один из них должен ждать второго, чтобы не получить в таблице двух строчек с одинаковым value, но разными id .
Не понятноМожет все-таки сначала цель скажешь? Чего добиться-то хочешь в итоге?
К чему, для чего эта совершенно непонятная сторока??
...
Рейтинг: 0 / 0
05.10.2016, 10:11
    #39320759
Insert FOR UPDATE
Возможно я привел плохой пример, я читал книгу по ораклу и там был очень подходящий пример:

Допустим есть таблица в которой каждая строка это бронь на то или иное место в кинозале. Т.е. там будут приблизительно такие поля:
ID,Время сеанса, место, ФИО человека.

И есть приложение работающее с этой таблицей, которое перед инсертом просматривает таблицу на предмет не занято ли это время-место. Так вот если оно будет смотреть на эту таблицу без FOR UPDATE , то может получиться что два человека забронируют одно место одновременно.

Я просто хотел повторить этот процесс, написать процедуру с использованием for update и запустить ее одновременно из двух разных сессий
...
Рейтинг: 0 / 0
05.10.2016, 10:13
    #39320762
Не понятно
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьумен,
тогда просто уникальный индекс добавь на поле value.
...
Рейтинг: 0 / 0
05.10.2016, 10:19
    #39320768
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменВозможно я привел плохой пример, я читал книгу по ораклу и там был очень подходящий пример:
Вот возьмите тот пример в оригинале и воспроизведите дословно, без отсебятины.
Потом разберите до последнего "end;"
Попробуйте позвать из нескольких сессий и т.п.
И когда поймете что это и как именно работает - начинайте эксперименты с изменением текстов.
Открытий на Вашем пути еще очень много.
...
Рейтинг: 0 / 0
05.10.2016, 10:20
    #39320771
Viewer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
Если уж вы хотите повторить, создать собственный test case, так вкладываете в него хоть какую-то логику событий. Логика событий и диктует логику реализации..
...
Рейтинг: 0 / 0
05.10.2016, 10:21
    #39320773
Insert FOR UPDATE
andrey_anonymous,
да в том и дело, что пример не был дословно описан было лишь упоминание что проблема решилась использованием for update
книга -Oracle для профессионалов. Архитектура, методики программирования и особенности версий
...
Рейтинг: 0 / 0
05.10.2016, 10:27
    #39320775
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменкнига -Oracle для профессионалов. Архитектура, методики программирования и особенности версий
Ну понятно.
Тома нашего Кайта надо читать ПОСЛЕ официальной доки, а не до.
Том реально предполагает, что его читатель уже "в теме".
Минимум, который надо освоить перед чтением Кайта или, упаси Бог, Льюиса и прочих Арупов Нандов, Кэрри Миллсапов или кого еще там найдете в магазине:
Application Development Guide на Вашу версию сервера + database concepts, как минимум - главы "Data concurrency and consistency"
Ну про SQL Reference вообще молчу.
...
Рейтинг: 0 / 0
05.10.2016, 10:29
    #39320777
Viewer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменпример не был дословно описан
Словами пример описан самодостаточно. Ну так и пробуйте... пишите код именно в той логике событий..
...
Рейтинг: 0 / 0
05.10.2016, 11:29
    #39320846
Insert FOR UPDATE
Viewer,
Код: plsql
1.
2.
3.
4.
5.
  CREATE TABLE ""BRON" 
   (	"MESTO" NUMBER, 
	"SEANS_DATE" DATE, 
	"FIO" VARCHAR2(20 BYTE)
   );



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create or replace PROCEDURE FOR_BRON (MESTO# NUMBER,SEANS_DATE# DATE,FIO# VARCHAR2)
IS
CNT NUMBER;
BEGIN
SELECT v INTO CNT FROM (SELECT COUNT(*) v FROM BRON WHERE MESTO=MESTO# AND SEANS_DATE=SEANS_DATE# );
IF CNT=0 THEN
INSERT INTO BRON VALUES (MESTO#,SEANS_DATE#,FIO#);
ELSE  Raise_application_error( -20001, 'Такая запись уже есть');
END IF;
COMMIT;
END;



Я сделал вот такую процедуру, она работает. Но я все равно не понимаю в каком месте надо прикручивать FOR UPDATE чтобы реализиовать то, о чем я писал. Проблема еще и в том что не удается "словить" момент когда при одновременном нажатии в таблицу попадут две строки с одинаковым mesto,seans_date и разными FIO
...
Рейтинг: 0 / 0
05.10.2016, 13:03
    #39320963
Viewer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменв каком месте надо прикручивать FOR UPDATE
Как звучит в переводе фраза "select for update "?
Где здесь insert ?
Для выполнения " for update " строка должна уже существовать.
По сути "матрица" мест кинозала в таблице уже расписана (зал ведь не резиновый, не сдувается и не раздувается, не так ли?)
Другое дело, что существующее место забронировано или нет.
Попробуйте подумать в этом направлении.
...
Рейтинг: 0 / 0
05.10.2016, 13:11
    #39320972
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменЯ сделал вот такую процедуру, она работает.
Не работает.
Чтобы она работала - на таблице bron необходим primary или unique key по полям (MESTO,SEANS_DATE)
...
Рейтинг: 0 / 0
05.10.2016, 13:42
    #39321015
Insert FOR UPDATE
andrey_anonymous,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
create or replace PROCEDURE FOR_BRON (MESTO# NUMBER,MESTO_DATE# DATE,FIO# VARCHAR2)
IS
CNT NUMBER;
BEGIN
FOR V IN (SELECT COUNT(1) OVER (ORDER BY 1) CNT FROM BRON S WHERE MESTO=MESTO# AND SEANS_DATE=MESTO_DATE# FOR UPDATE) LOOP
       CNT := V.CNT;
      EXIT;
    END LOOP;
    
IF CNT=0 THEN
INSERT INTO BRON VALUES (MESTO#,MESTO_DATE#,FIO#);
ELSE  Raise_application_error( -20001, 'УЖЕ ЕСТЬ ТАКАЯ ЗАПИСЬ, СЛЫШ');
END IF;
COMMIT;
END;



Эхх, вроде бы так должно работать, только не знаю как в этом удостовериться.
По поводу unique key, если сделать такой ключ, то как я понимаю при попытке внести неправильную строку оракл выдаст что-то вроде "нарушено ограничение целостности" . Просто хотелось бы чтобы строки даже не пытались вставляться, чтобы процедура не позволяля
...
Рейтинг: 0 / 0
05.10.2016, 13:47
    #39321020
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменПросто хотелось бы чтобы строки даже не пытались вставляться, чтобы процедура не позволяляГарантию может дать только уникальный ключ. Всё твои потуги - наивны.
...
Рейтинг: 0 / 0
05.10.2016, 13:57
    #39321030
Insert FOR UPDATE
Elic,
Окей, я понял что самый надежный способ- уникальный ключ.
Но все-таки интересно, в чем проблема этой процедуры, почему она не обеспечивает того же самого?
...
Рейтинг: 0 / 0
05.10.2016, 14:00
    #39321035
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
неоченьуменПросто хотелось бы чтобы строки даже не пытались вставляться, чтобы процедура не позволяля
Удостовериться:
в двух сессиях параллельно запустить
begin
FOR_BRON (7654, trunc(sysdate),'Вася Пупкин');
end;
затем, когда отработает - закоммитить обе сессии.
Убедиться, что данные задублированы.

Чтобы процедура "просто не позволяла" - то нужно наложить ограничение уникальности и обрабатывать exception в процедуре.
...
Рейтинг: 0 / 0
05.10.2016, 14:41
    #39321074
j2k
j2k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert FOR UPDATE
И это, в каком кинотеатре не стоит покупать билеты онлайн? :)
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Insert FOR UPDATE / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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