Гео-репликация Azure SQL с.NET NHibernate sp_wait_for_database_copy_sync проблема

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

В настоящее время в тестировании у нас есть два экземпляра - основной и дополнительный *, один из которых находится в США, а другой в Европе.

Проблема

Недавно обновленные данные из первичной базы данных, по-видимому, не доступны во вторичной базе данных, даже если вызывается sp_wait_for_database_copy_sync, что должно обеспечить это.

Шаги, чтобы воспроизвести проблему

  1. Пользователь подключается к вторичному экземпляру
  2. Пользователь обновляет данные ("ОБНОВЛЕНИЕ" или "ВСТАВКА", которые идут в первичную базу данных)
  3. Сделка совершена
  4. Процедура sp_wait_for_database_copy_sync вызывается с соответствующими параметрами, чтобы гарантировать, что данные будут реплицированы во вторичный экземпляр, когда вызов обновления разблокируется
  5. Как только вызов обновления разблокируется, на вторичной базе данных делается попытка получения данных (включая недавно обновленные или вставленные).
  6. Недавно обновленные или вставленные данные не содержатся в результирующем наборе, что делает их отображаемыми при том, что процедура синхронизации копии базы данных не гарантировала, что данные будут реплицированы при разблокировании вызова обновления

Технические детали реализации

Когда объект должен быть обновлен, транзакция зафиксирована и синхронизация данных обеспечена, следующие три строки кода вызываются по порядку:

  1. ISession.Save(object obj) используется для сохранения новых объектов
  2. ISession.Flush() используется для совершения транзакции
  3. ISession.CreateSQLQuery("EXEC sys.sp_wait_for_database_copy_sync @target_server = N\'secondary-server\', @target_database = N\'database\';").ExecuteUpdate() используется для выполнения процедуры синхронизации блокировки вызовов

Вопросы

Что может быть не так с этими тремя строками кода? Возможные виновники, которых я вижу:

  1. ISession.Flush не выполняется синхронно, поэтому при выполнении хранимой процедуры блокировки транзакция еще не зафиксирована
  2. ISession.CreateSQLQuery("EXEC sys.sp_wait_for_database_copy_sync @target_server = N\'secondary-server\', @target_database = N\'database\';").ExecuteUpdate() на самом деле не блокируется.

Будем весьма благодарны за любые идеи о том, как устранить неполадки, возникшие выше, или о некоторых других проблемах, которые вы видите.

  • Первичное и вторичное в этом случае относятся к настройке гео-репликации.

3 ответа

Когда вы говорите "мастер", то здесь вы ссылаетесь на первичную базу данных в отношениях гео-репликации или логическую основную базу данных?

Я забыл опубликовать здесь, но проблема заключалась в том, что следующая процедура, хотя и блокировала, на самом деле не гарантировала, что когда-то разблокированные данные будут доступны во всех случаях: sp_wait_for_database_copy_sync.

Гео-репликация Azure SQL DB предназначена для пользовательских баз данных, а не для основной базы данных. Документы будут обновлены, чтобы прояснить это.

NHibernate является синхронным. ISession.Flush всегда синхронно. Но если вы находитесь в распределенном TransactionScope (проверять System.Transactions.Transaction.Current?.TransactionInformation?.DistributedIdentifier ?? default(Guid) != Guid.Empty), затем запускается MSDTC и вызывает фактическую фиксацию в базе данных асинхронно, что в конечном итоге происходит после удаления области. Узнайте больше здесь.,

Я не уверен, что Azure принимает распределенные транзакции, так что это может не стать причиной ваших проблем.

Если вы находитесь в случае распределенной транзакции, то в зависимости от блокировок, вызванных вашими запросами / настройками базы данных /..., вам придется либо считывать принятые данные из базы данных, полагаясь на блокировки транзакций, чтобы блокировать вас до тех пор, пока на самом деле фиксируется, затем выполните синхронизацию. Или, если вы не заблокированы, опрашивайте базу данных до тех пор, пока не получите данные (что, конечно, даже хуже для производительности), а затем выполните синхронизацию.

Кстати, я не знаю, как работает георепликация Azure, но если он также использует MSDTC, то у него могут возникнуть эти асинхронные проблемы.

О SQL Exec не будучи фактически заблокированным, тогда это будет проблемой SQL Azure.

Другие вопросы по тегам