Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
Поднимаю эту тему во второй раз, в первый никто не отозвался. Итак, вопрос следующий: есть merge replication, хочется вместо стандартного priority-based resolver'а использовать другой. Если быть точнее, то нужен datetime-based resolver (кто последний менял запись, тот и победитель). С SQL Server'ом поставляются сэмплы, среди которых есть как раз нужный мне resolver. Компилирую его, подключаю, ошибок нет ни во время создания публикации, ни во время синхронизации. Но на выбор победителя это никак не повлияло - такое ощущение, что по-прежнему работает стандартный resolver. У кого-нибудь есть опыт в данном вопросе ? Поделитесь, плз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2001, 11:29 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
2 GreenSunrise сейчас пробую сделать стандартным резолвером по датам, вываливается ошибка (здесь уже был вопрос) дубликата ключа, если поборю - скажу, завтра попробую процедурой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2001, 12:25 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
В общем поизвращался я с merge репликацией немного, стандартный резолвер по datetime мне запустить не удалось, все время вылезала ошибка по дубликату ключа Можно будет еще попробовать, если время будет. А вот свой резолвер у меня заработал вот его текст: CREATE PROC sp_test @tableowner sysname, -- this is the publisher owner, but we assume its always dbo at subscriber. @tablename sysname, -- this is the publisher tablename, but we assume its identical at subscriber. @rowguid uniqueidentifier, @subscriber sysname, @subscriber_db sysname, @log_conflict int OUTPUT, -- output param for if to log conflict for later resolution. @conflict_message nvarchar(512) OUTPUT -- output param for message to be given about resolution if conflict is loggged. AS DECLARE @pub_qualified_name NVARCHAR(392), -- 3*128 + 2 spaces + 6 quotes @sub_qualified_name NVARCHAR(392), @select_string NVARCHAR(2000), @rowguidvar uniqueidentifier, @ResolvedQuestionID int, @SubCurDateTime datetime SELECT @pub_qualified_name=QUOTENAME(db_name())+'.'+QUOTENAME(@tableowner)+'.'+QUOTENAME(@tablename) SELECT @sub_qualified_name=QUOTENAME(@subscriber_db)+'.'+QUOTENAME('dbo')+'.'+QUOTENAME(@tablename) SELECT @select_string= 'SELECT CurDateTime into ##t FROM OPENQUERY('+QUOTENAME(@subscriber)+','+'"SELECT CurDateTime FROM ' + @sub_qualified_name + " WHERE ROWGUIDCOL='" + convert(varchar(36),@rowguid) + "'" + ' ") ' exec(@select_string) select @SubCurDateTime = CurDateTime from ##t drop table ##t SELECT @select_string= 'SELECT * FROM OPENQUERY('+QUOTENAME(@subscriber)+','+'"SELECT * FROM ' + @sub_qualified_name + " WHERE ROWGUIDCOL='" + convert(varchar(36),@rowguid) + "'" + ' ") ' if exists(select 1 from AnswerSync where CurDateTime > @SubCurDateTime and rowguid = @rowguid) select * from AnswerSync where rowguid = @rowguid else exec(@select_string) RETURN(0) GO Прошу не пинать меня за эффективность просто очень хотелось что бы заработало, да и опыта у меня в этом никакого. Поправки от знающего народа мы с GreenSunrise (не против? ) с удовольствием примем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.05.2001, 06:52 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
Genady! Спасибо большое за процедуру, на днях попробую, скажу что получилось... Любые поправки и комментарии принимаются с благодарностью ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.05.2001, 07:39 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
Genady! Класс Процедура в несколько измененном виде заработала, причем, похоже, вполне успешно. В связи с этим возник такой каверзный вопрос - есть у меня поле CurDateTime, семантика которого, думаю, вопросов не вызывает Так вот, если повесить на него триггер, который будет устанавливать его в getdate() при insert'ах и update'ах, то получим такое поведение при репликации: - начинается синхронизация - обнаруживается конфликт (изменения в строке с одним и тем же guid'ом) - срабатывает наша процедура, которая выявляет победителя - сиквел апдейтит побежденную запись - это приводит к изменению поля CurDateTime на побежденном, причем запись, естественно, имеет более "свежее" значение, чем победитель - при следующей синхронизации эта запись опять выявляется как конфликтующая по полю CurDateTime, выравнивается, что приводит к новому изменению и т.д. - бесконечно вкусный апельсин Если такой триггер не вешать, то нет гарантии, что любая операция проведенная с клиента или откуда-нибудь еще, проапдейтит это поле. Как же мне заполнять это поле ? Единственный выход, который я пока вижу - триггер не вешать, в процедуре разрешения конфликтов присваивать ему значение этого же поля победителя, из репликации это поле исключить (самая важная деталь). Не знаю, есть ли в семерке выбор полей, участвующих в репликации, или можно указать только таблицу целиком... Что скажете по поводу CurDateTime ? Может, есть лучший выход, просто я его не вижу ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2001, 13:40 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
>при следующей синхронизации эта запись опять выявляется как конфликтующая по полю CurDateTime, выравнивается, что приводит к новому изменению и т.д. - бесконечно вкусный апельсин А почему вы так думаете? Если я ничего не путаю, то конфликт возникает только в том случае, если с момента последней синхронизации были обновлены записи и на издателе и на подписчике. Я бы посоветовал провести эксперимент и посмотреть что будет, думаю в худшем случае у Вас при каждой синхронизации просто будет попытка выравнять CurDateTime (безуспешно конечно) Это конечно не решение проблемы, немного подумаю затем отвечу ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2001, 13:59 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
Именно так все и происходит - при каждой синхронизации происходит перезапись поля CurDateTime. Только это не так безопасно, как кажется - количество записей растет, база постепенно пухнет - и репликационный траффик растет и растет (( Меня тут еще мысля посетила... А что, если поиграться с ключиком NOT FOR REPLICATION для триггера, который изменяет значение CurDateTime ? Если что получится, напишу... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2001, 06:37 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
2 GreenSunrise Провел экспериментик, так вот, не будет Вам вкусных апельсинов CurDateTime обновляется и на подписчике и на издателе, причем обновляется один раз, при повторной синхронизации обновления не было. экспериментик проводил два раза, первый раз разница на подписчике и издателе была в 1 секунду, второй раз разницы вообще не было, тем не менее ни в первом ни во втором случае повторного обновления не было. P.S. Издатель MS SQL 2000, подписчик MS SQL 7.0, оба сервера являются инстансами на одном компе. Удачи ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2001, 06:41 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
Хм... Да, синхронизация проводится не бесконечно. Например, вставляю запись на один сервер, она появляется на втором, потом апдейтится CurDateTime на первом и все. Процесс прекращается. Вот только теперь у меня вопрос - а почему так ? Почему последний апдейт не привел к обновлению этих данных снова на втором сервере ? Это прошло мимо репликационных триггеров ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2001, 07:37 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
Total success!!! Делаем триггер for insert/update NOT FOR REPLICATION, который устанавливает поле CurDateTime в getdate(). Настраиваем репликацию с time-based resolver'ом. И все работает Обновление происходит только один раз, как и нужно, CurDateTime одинаковый на обоих серверах. Никаких извратов с выбрасыванием колонки CurDateTime не понадобилось. Ниже приведу подправленный мной текст stored proc. CREATE PROC sp_test @tableowner sysname, -- this is the publisher owner, but we assume its always dbo at subscriber. @tablename sysname, -- this is the publisher tablename, but we assume its identical at subscriber. @rowguid uniqueidentifier, @subscriber sysname, @subscriber_db sysname, @log_conflict int OUTPUT, -- output param for if to log conflict for later resolution. @conflict_message nvarchar(512) OUTPUT -- output param for message to be given about resolution if conflict is loggged. AS DECLARE @pub_qualified_name NVARCHAR(392), -- 3*128 + 2 spaces + 6 quotes @sub_qualified_name NVARCHAR(392), @select_string NVARCHAR(2000), @rowguidvar uniqueidentifier, @ResolvedQuestionID int, @SubCurDateTime datetime, @PubCurDateTime datetime SELECT @pub_qualified_name = QUOTENAME(db_name()) + '.' + QUOTENAME(@tableowner) + '.' + QUOTENAME(@tablename) SELECT @sub_qualified_name =QUOTENAME(@subscriber) + '.' + QUOTENAME(@subscriber_db) + '.' + QUOTENAME('dbo') + '.' + QUOTENAME(@tablename) SELECT @select_string = 'SELECT @SubCurDateTime = CurDateTime FROM ' + @sub_qualified_name + ' WHERE objectGUID = @rowguid' exec sp_executesql @select_string, N'@SubCurDateTime datetime out, @rowguid uniqueidentifier', @SubCurDateTime = @SubCurDateTime out, @rowguid = @rowguid SELECT @select_string = 'SELECT @PubCurDateTime = CurDateTime FROM ' + @pub_qualified_name + ' WHERE objectGUID = @rowguid' exec sp_executesql @select_string, N'@PubCurDateTime datetime out, @rowguid uniqueidentifier', @PubCurDateTime = @PubCurDateTime out, @rowguid = @rowguid if @PubCurDateTime > @SubCurDateTime set @select_string = 'SELECT * FROM ' + @pub_qualified_name + ' WHERE objectGUID = @rowguid' else set @select_string = 'SELECT * FROM ' + @sub_qualified_name + ' WHERE objectGUID = @rowguid' exec sp_executesql @select_string, N'@rowguid uniqueidentifier', @rowguid = @rowguid RETURN(0) GO Изменения коснулись выборки CurDateTime - там вовсе незачем было использовать временную таблицу; и последней части sp, где формируется нужный select - там откуда-то всплыла таблица AnswerSync (видимо, ты на ней тренировался ) Genady, спасибо огромное!!! Ты меня сдвинул с мертвой точки и здорово помог Удачи! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2001, 08:38 |
|
||
|
Merge replication & custom conflict resolver
|
|||
|---|---|---|---|
|
#18+
>Изменения коснулись выборки CurDateTime - там вовсе незачем было использовать временную таблицу; Дык на эффективность я и не претендовал, пробовал просто шоб получилось >видимо, ты на ней тренировался Умгу, отрабатывал приемы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2001, 08:51 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32007790&tid=1826445]: |
0ms |
get settings: |
11ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
217ms |
get topic data: |
13ms |
get forum data: |
4ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
| others: | 261ms |
| total: | 584ms |

| 0 / 0 |
