Изменение настроек репликации транзакцией в горячем режиме   

Некоторое время назад мне нужно было решить задачу по настройке репликации транзакцией БД под 1С из одного сервера на другой, при реализации я столкнулся со следующей проблемой. В основном, проблему можно сформулировать так, что при изменении структуры БД мастер репликации требует переформирования всей схемы БД, а не конкретно выбранного объекта. Также поставленные на репликацию таблицы нельзя никаким переименовывать, удалять, что 1С и делает при изменении структуры БД. То есть, конечно, можно было перед изменением структуры снимать все (можно конечно только измененные, но их нужно знать заранее) таблицы с репликации, а затем ставить заново, но эта операция требует гораздо большего времени (и сетевого трафика), чем изменение настройки репликации конкретного объекта.

Нужно было решить следующие проблемы:

   1) Возможность изменения структуры реплицируемых объектов
   2) Возможность определения измененных объектов до начала изменения структуры конфигурации 1С и после.
   3) Изменение настройки правил репликации только для измененных объектов.
   4) На издателе формировался триггер for update в котором не использовалась конструкция set nocount on.

Первая проблема решалась изменением служебных полей определяющих статус реплицируемой таблицы в sysobjects.

Вторая проблема решалась сохранением слепка sysobjects до изменений и сравнение его с sysobjects после изменений.

drop table copysysobjects
select * into copysysobjects from sysobjects where xtype='U' and status>0

--сохранение слепка до изменений

select id,name from sysobjects cso where cso.id not in (select id from copysysobjects)
and xtype='U'
and status>0

--определение измененных объектов

Третья проблема решалась с помощью использования хранимых процедур sp_dropsubscription, sp_droparticle,

для снятия объектов, определенными предыдущим скриптом, с репликации(с подписки и издателя соответственно). А также с помощью sp_addarticle, sp_addsubscription соответственно для постановки на репликацию. Нужно отметить также, что для

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

Четвертая проблему можно решать несколькими способами. Один из них это изменение шаблона репликационного триггера. Второй это изменение триггеров дополнительным скриптом.(Хотя первый способ мне кажется более красивым и надежным)

declare @str char(8000)
declare @dropstr char(8000)
declare @trigger_name char(100)

declare Mylog cursor local fast_forward for
select rtrim(c.text),rtrim(o.name) from dbo.syscomments c, dbo.sysobjects o
where o.id = c.id
and o.name like '%sp_MSsync_upd_trig_%'
order by c.number, c.colid
open Mylog
fetch Mylog into @str,@trigger_name
while (@@fetch_status<>-1)
begin
set @dropstr='drop trigger '+rtrim(@trigger_name)
set @str=rtrim(replace(@str,' declare @rc int',' declare @rc int set nocount on'))
set @str=rtrim(@str)+'set nocount off'
select @str
exec(@dropstr)
exec(@str)
fetch Mylog into @str,@trigger_name
end
close Mylog
deallocate Mylog

P.S. У автора статьи на базе репликации транзакцией для 1С есть уже готовое, прошедшее внедрения, решение.

Для описанной выше задачи оказалось более эффективным решение не предполагающее изменение в структуре БД 1С. То есть измененный мастер репликации MSSQL вообще не вносит никаких изменений в структуру существующих таблиц.

Обсуждение статьи

 


 

Перепечатка, воспроизведение в любой форме, распространение, в том числе в переводе, любых материалов с сайта www.softpoint.ru возможны только с письменного разрешения компании "СофтПоинт". Это правило действует для всех без исключения случаев, кроме тех, когда в материале прямо указано разрешение на копирование (основание: Закон Российской Федерации "Об авторском праве и смежных правах").