powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Блокировка в цикле. Цикл на ожидание изменения строки.
15 сообщений из 15, страница 1 из 1
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39818949
Ёжик25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В MS SQL:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 
create table test1 (q int)
insert into test1 values (null)

declare @w int
while 1=1 
begin
 set @w = (select q from test1)
 if @w is not null break else CONTINUE 
end
select @w


переменная @w ожидает изменения строки, и при изменении выводит значение. При этом вторая транзакция ее изменяет (update dbo.test1 set q = '1'. При таких условиях никто ничего не блокирует, и вторая транзакция успевает изменить строку между циклами присвоения (как я понимаю), и цикл отрабатывает так как надо. На "ожидание".

А вот в PG так не получается.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE OR REPLACE FUNCTION dbo.test()
 RETURNS int
 LANGUAGE plpgsql
AS $function$
 declare w int;
begin
	loop
	w = (SELECT q FROM  dbo.test1 );
	EXIT WHEN w IS NOT NULL;
CONTINUE WHEN w IS NULL;
	end loop;
	return w;
END;
$function$
;


вторая update dbo.test set q = '1', которая зависает, и как я понимаю, на блокировке таблицы. Соответственно, при запуске функции идет ожидание изменения, но оно не может произойти, так как идет блокировка.

То есть при входе в цикл MS SQL выполняет независимые селекты, каждый раз освобождая таблицу, а PG ее блокирует до выхода из цикла. Подскажите, как задать цикл ожидания изменения данных в таблице.

Прошу, подскажите, как лучше задать цикл ожидания на изменения в PG.
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819018
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25,

А не проще повесить ON UPDATE триггер?..
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819033
Ёжик25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovЁжик25,

А не проще повесить ON UPDATE триггер?..

а как тогда возвращать функции все это дело? идет тело функции, в нем некий набор команд, одна из которых ожидает изменения в таблице (допустим, удаленный сервер пишет в таблицу некое значение, и база должна ожидать возврат этого значения). Получает значение и работает с ним дальше. В SQL бесконечным циклом прекрасно все работает, делаешь сложную логику "ожидания" значения. В PG пришел в тупик. Триггер что может тут сделать?
в общем, проблема именно в этом, как я понимаю...тело цикла блокирует таблицу. Надо блокировку убрать. Или же каким то образом заверашать транзакцию на чтение внутри тела цикла, что бы опять же ушла блокировка, и значение в таблице можно было проапдейтить.
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819087
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25,

Копировать подход MS-SQL в лоб не самая лучшая идея. Что вы хотите реализовать-то?..

Мне кажется, что вам лучше поступить иначе: не сидеть и ждать пока запись изменится, а:
- повесить триггер, проверять изменения нужных полей на нужные значения
- по факту изменений, складывать event в очередь
- читать внешним обработчиком event-ы из очереди и продолжать процессинг.

Для очереди рекомендую PgQ, там event-ы батчуются по времени и/или количеству.
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819090
alex-ls
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вообще если я правильно понимаю в MS SQL - изменение блокирует чтение, а Postgre версионная БД, потому механизмы, основанные на понимании блокировок как в MS SQL тут работать не будут
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819101
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex-ls,

видимо ТС пытается организовать очередь типа select for update, и ,видимо, на грязном чтении ресурса "ку" в м$скл

но в пж нет грязного чтения. т.е. вообще.
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819125
alex-ls
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqalex-ls,

видимо ТС пытается организовать очередь типа select for update, и ,видимо, на грязном чтении ресурса "ку" в м$скл

но в пж нет грязного чтения. т.е. вообще.
вот-вот, единственное я не понял, он пишет что-то не то про блокировки в PG, что-то совсем несуразное... блокировка таблицы...
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819693
Ёжик25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задача: создать функцию "на ожидание" любым доступным методом в PG. Я уже описал, для чего допустим это надо. Есть две базы, на PG и на MS SQL. Приложение посылает в обе запуск процедуры (в MS SQL) и функции (в PG) независимо. Однако на PG функция должна ожидать изменения значения в таблице, которую изменяет процедура на SQL. При этом скульная проца может изменять таблицу как на PG так и у себя. То есть не важно, где такая таблица будет.

Поэкспериментировав, выяснил следующее:
1. Если таблица на PG - то цикл ее блокирует на изменение однозначно.
2. Если таблица на SQL - то цикл делает 6 итерраций SELECT (судя по профайлеру) и вылетает с ошибкой "An I/O error occurred while sending to the backend postgresql". Кстати почему 6 для меня загадка. При этом если скульная проца успевает изменить таки значение в таблице - то цикл на PG отрабатывает нормально и возвращает измененное значение. Можно поиграться тут с pg_sleep, но это конечно так себе решение.
3. Если создан FOREIGN TABLE у PG сам на себя - то блокировка так же идет как в пункте 1.
4. Если таблица FOREIGN TABLE на другом сервере PG - то блокировки нет, изменение удаленной таблицы проходит, но из цикла не выходит.

Все это конечно не решает поставленной задачи.
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819704
alex-ls
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25Задача: создать функцию "на ожидание" любым доступным методом в PG. Я уже описал, для чего допустим это надо. Есть две базы, на PG и на MS SQL. Приложение посылает в обе запуск процедуры (в MS SQL) и функции (в PG) независимо.
асинхронный запуск в 2 разные базы? тогда проверять должно приложение, которое инициирует этот запуск, а MS SQL и PostgreSQL сообщать когда закончат. По-моему так более логично
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819722
Ёжик25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex-ls,

конечно логично). Только нет возможности вмешиваться в работу приложения и новую логику в нем делать. Исключительно есть то, что имеем сейчас.
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819740
alex-ls
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25alex-ls,

конечно логично). Только нет возможности вмешиваться в работу приложения и новую логику в нем делать. Исключительно есть то, что имеем сейчас.
тогда может запустить в 3 потока:
1. делает, что надо в базе MS SQL
2. делает, что надо в базе PosgreSQL
3. просто в цикле или по таймеру проверяет, что п.1 и п.2 сделали свою работу и рапортует приложению, что все закончено
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819743
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25Задача: создать функцию "на ожидание" любым доступным методом в PG.


повторяю: в пж нет грязного чтения.

на пальцах~любой апдейт лочит (на изменение другими транзами) изменяемую запись до коммита, но не лочит на чтение ее старую версию

любое чтение читает :

либо ранее (окончательно) закомиченные другими транзами версии (в зависимости от уровня изоляции -- на момент того или иного снепшота -- либо старта текущего стейтмента (рид-коммитед), либо на момент старта транзакции (рипитебл рид/сериалайзебл))

, либо последнюю версию строки, измененную в самой транзакции (если строка залочена текущей и в ней изменялась хоть 100500 раз)


если вам нужна только очередь -- можете попробовать тот или иной транзакционный адвайзори_лок
https://postgrespro.ru/docs/postgresql/11/functions-admin#FUNCTIONS-ADVISORY-LOCKS
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819819
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25В MS SQL:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 
create table test1 (q int)
insert into test1 values (null)

declare @w int
while 1=1 
begin
 set @w = (select q from test1)
 if @w is not null break else CONTINUE 
end
select @w


переменная @w ожидает изменения строки, и при изменении выводит значение. При этом вторая транзакция ее изменяет (update dbo.test1 set q = '1'. При таких условиях никто ничего не блокирует, и вторая транзакция успевает изменить строку между циклами присвоения (как я понимаю), и цикл отрабатывает так как надо. На "ожидание".

А вот в PG так не получается.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE OR REPLACE FUNCTION dbo.test()
 RETURNS int
 LANGUAGE plpgsql
AS $function$
 declare w int;
begin
	loop
	w = (SELECT q FROM  dbo.test1 );
	EXIT WHEN w IS NOT NULL;
CONTINUE WHEN w IS NULL;
	end loop;
	return w;
END;
$function$
;


вторая update dbo.test set q = '1', которая зависает, и как я понимаю, на блокировке таблицы. Соответственно, при запуске функции идет ожидание изменения, но оно не может произойти, так как идет блокировка.

То есть при входе в цикл MS SQL выполняет независимые селекты, каждый раз освобождая таблицу, а PG ее блокирует до выхода из цикла. Подскажите, как задать цикл ожидания изменения данных в таблице.

Прошу, подскажите, как лучше задать цикл ожидания на изменения в PG.

и там, и там бомбежка без пауз - это интересное решение.
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39819840
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёжик25Прошу, подскажите, как лучше задать цикл ожидания на изменения в PG.

Вы что то сильно не так делаете. Т.е. схема у вас ну очень кривая но в общем должна работать.
Более того именно ваш код - работает.

Вот только что


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
консоль 1
mboguk=# create schema dbo;
CREATE SCHEMA
mboguk=# CREATE OR REPLACE FUNCTION dbo.test()
 RETURNS int
 LANGUAGE plpgsql
AS $function$
 declare w int;
begin
 loop
 w = (SELECT q FROM  dbo.test1 );
 EXIT WHEN w IS NOT NULL;
CONTINUE WHEN w IS NULL;
 end loop;
 return w;
END;
$function$
;
CREATE FUNCTION
mboguk=# create table dbo.test1 (q integer);
CREATE TABLE
mboguk=# select dbo.test();
ждем...

консоль 2:
mboguk=# insert into dbo.test1 values (5);
INSERT 0 1


консоль 1:
 test 
------
    5
(1 row)



Если у вас происходит где то блокировка то
1)покажите что при этом в pg_stat_activity у вас
2)включите полный лог запросов и приведите его (чтобы понять что где и в какой последовательности вызывалось).
...
Рейтинг: 0 / 0
Блокировка в цикле. Цикл на ожидание изменения строки.
    #39820299
Ёжик25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Решил проблему с помощью механизма автономных транзакций через dblink_exec на саму себя, которая открывает отдельное соединение и тем самым обеспечивает автономность нужной транзакции даже в цикле. Без блокировок ресурсов. Всем спасибо. Вопрос закрыт.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Блокировка в цикле. Цикл на ожидание изменения строки.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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