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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как на таблицу наложить блокировку? 
:(
    Опции темы
crook4
Дата 23.4.2009, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Смысл в следующем:
есть 2 БД, в БД slave есть таблица tab_slave, которая синхронизируется с таблицей tab_1 из БД test.
На время синхронизации надо наложить блокировки на эти таблицы, чтобы пользователи не могли
работать с этими таблицами.

Вот написал функцию для синхронизации:
Код

--коннект к базе
    perform dblink_connect('host=127.0.0.1 dbname=slave user=postgres password=zzcz2com');

    --для всех записей в таблице inserted
    FOR myrec IN SELECT * FROM inserted LOOP

    --если время реплики меньше времени вставки
    if ((SELECT * from dblink('host=127.0.0.1 dbname=slave user=postgres password=zzcz2com',
    'select tm from time_rep limit 1') as t (time timestamp without time zone)) < myrec.time) 
    then
    
    --в таблицы клиента вставляем строки, которые были изменены, т.е. проверяем таблицу inserted, если время вставки
    --в таблицу позже временя последней синхронизации, то ищем строку в таблицу tab_1 по идентификатору, укаанному в
    --таблице inserted
    
    perform dblink_exec('insert into tab_slave select * from dblink('|| chr(39) ||'host=127.0.0.1 dbname=test user=postgres password=zzcz2com'||
    chr(39)|| ',' || chr(39) || 'select * from tab_1 where id =' || myrec.id || chr(39) ||') as t (id integer, name varchar(20))');
    
    count = count+1;
    end if;
    end loop;

    --для всех записей в таблице deleted
    FOR myrec IN SELECT * FROM deleted LOOP

    --если время реплики меньше времени вставки
    if ((SELECT * from dblink('host=127.0.0.1 dbname=slave user=postgres password=zzcz2com',
    'select tm from time_rep limit 1') as t (time timestamp without time zone)) < myrec.time) 
    then
    
    --из таблицы клиента удаляем строки, которые были удалены на сервере, т.е. проверяем таблицу deleted, если время удаления
    --в таблицу позже временя последней синхронизации, то удаляем из таблицы клиента строку с идентификатором, укаанном в
    --таблице deleted
    
    perform dblink_exec('delete from tab_slave where id =' || myrec.id);
    
    count = count+1;
    end if;
    end loop;

    --для всех записей в таблице deleted
    FOR myrec IN SELECT * FROM updated LOOP

    --если время реплики меньше времени вставки
    if ((SELECT * from dblink('host=127.0.0.1 dbname=slave user=postgres password=zzcz2com',
    'select tm from time_rep limit 1') as t (time timestamp without time zone)) < myrec.time) 
    then
    
    --из таблицы клиента удаляем старык строки, которые были обновлены на сервере, а зетем считываем новую и 
    --всавляем ее, т.е. проверяем таблицу updeted, если время изменения
    --в таблице позже временя последней синхронизации, то удаляем из таблицы клиента строку с идентификатором, укаанном в
    --таблице deleted, а затем вставляем новую
    
    perform dblink_exec('delete from tab_slave where id =' || myrec.id);

    perform dblink_exec('insert into tab_slave select * from dblink('|| chr(39) ||'host=127.0.0.1 dbname=test user=postgres password=zzcz2com'||
    chr(39)|| ',' || chr(39) || 'select * from tab_1 where id =' || myrec.id || chr(39) ||') as t (id integer, name varchar(20))');
    
    count = count+1;
    end if;
    end loop;
    
    --обновляем время проведенной синхронизации в удаленной бд
    --perform dblink_exec('update time_rep set tm=' || quote_literal((now()))); 
    --диссконект
    perform dblink_disconnect();


Здесь сначала проводится синхронизация по вставкам, удалениям и потом обновлениям.
Как теперь тут наложить блокировки???
PM MAIL   Вверх
LSD
Дата 23.4.2009, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 3
Всего: 538



Ну в своей базе можно использовать LOCK, но вот можно ли наложить LOCK на таблицу в удаленной базе, этот вопрос надо проверить.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
pythonwin
Дата 23.4.2009, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 1
Всего: 36



crook4, у тебя обе БД находятся на одном сервере или разных?
у меня было аналогичная задача, только на разных серверах со слабым каналом между ними - сделал через copy
1) на сервере 1 создал промежуточную таблицу и из таблицы1 на сервере 1 запросом вставил данные которые нужно синхронмизировать
2) выгрузил данные из промежуточной таблицы в файл
3) файл скопировал на сервер2 - это решается специальным скриптом или rsync или чем-то аналогичным
4) на сервере2 выполнил загрузку данных через copy из файла в промежуточную таблицу и вставил запросом из промежуточной таблицы, те данные, которых нет в таблице2 на сервере2  и обновил из промежуточной таблицы данные, которые изменились
5) блокировку снял
PM WWW GTalk Jabber   Вверх
crook4
Дата 23.4.2009, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



У меня БД на разных серверах, канал нормальный (локальная сеть).
Функция отрабатывает нормально, но я пока не учел блокировки, а без них поидее не правильно.
Когда пишу так:
Код

CREATE OR REPLACE FUNCTION table_insr() 
returns integer as
$body$
declare 
    count integer =0;
    myrec record;
begin
     begin work -- ругается тут
     lock tab_1;
     .......код синхронизация (первый пост)
     commit work;
end;
$body$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION table_insr() OWNER TO postgres;


PG не пропускает "begin work"...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PostgreSQL | Следующая тема »


 




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


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

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