Восстановить из SQL ошибки пакетного прерывания внутри транзакции? Альтернатива? - PullRequest
0 голосов
/ 12 ноября 2009

Я ищу способ продолжить выполнение транзакции, несмотря на ошибки при вставке данных с низким приоритетом. Кажется, что реальная вложенная транзакция может быть решением, но они не поддерживаются SQL Server 2005/2008. Другим решением было бы иметь логику, чтобы решить, является ли ошибка критической или нет, но может показаться, что это также невозможно.

Вот более подробно мой сценарий:

Данные периодически вводятся в базу данных с использованием ADO.NET/C#, и, хотя некоторые из них имеют жизненно важное значение, некоторые также могут отсутствовать без проблем. Когда вставки сделаны, для данных сделаны некоторые вычисления. (И жизненно важный, и не жизненно важный) Весь этот процесс находится внутри транзакции, поэтому все остается в синхронизации.

В настоящее время используются точки сохранения транзакций, и частичные откаты выполняются для исключений, которые происходят во время не жизненно важных операций вставки. Однако это не работает для ошибок «пакетного прерывания», которые автоматически откатывают всю транзакцию. Я понимаю, что некоторые ошибки являются критическими, но такие вещи, как сбой приведения, рассматриваются SQL Server как ошибки пакетного прерывания. ( Информация об пакетных ошибках ) Я пытаюсь предотвратить эти ошибки, приводящие к сбою всей вставки, если они возникают на данных с низким приоритетом.

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

Спасибо за вашу помощь.

Ответы [ 2 ]

1 голос
/ 12 ноября 2009

К сожалению, сделать это невозможно, как вы описали (здесь ключевую роль играет полная поддержка вложенных транзакций). Несколько вещей, о которых я могу думать, которые использовались, чтобы обойти это в прошлом:

  1. Наилучшим вариантом, вероятно, будет разделение команд на важные / не важные команды, которые могут выполняться по-разному, естественно, для этого потребуется, чтобы они не зависели от порядка друг друга

  2. Может также использоваться подход, основанный на обмене сообщениями (см. Компонент Service Broker ), в котором вы выполняете встроенные первичные команды и помещаете неосновные команды в очередь для последующего / отдельного выполнения. Пересылка в очередь будет транзакционной в пределах пакета, но выполнение команды, когда вы выходите из очереди, будет отдельным. Это также потребует, чтобы они не зависели друг от друга.

  3. Если зависит от порядка, вы можете использовать подход обмена сообщениями для всего, что обеспечит порядок и может иметь отдельные сообщения для каждой операции, а затем сгруппировав их вместе (через группы разговоров), вы сможете вытащить их из очереди. чтобы также использовать отдельные транзакции для каждого «типа» операции (т.е. первичной или неосновной). Это потребует некоторого специального кодирования с вашей стороны, если все сгруппированные сообщения должны быть одной автономной операцией, но могут быть выполнены.

  4. Я не решаюсь даже упомянуть этот вариант, потому что это ужасный вариант, но для полного раскрытия, я полагаю, вы могли бы рассмотреть его на свое усмотрение, если считаете, что он подходит (но это определенно не та архитектура, которая будет применяться практически по любому сценарию). Вы можете использовать xp_cmdshell для вызова командной строки и выполнения sqlcmd / osql для некритических задач - это выполнение sqlcmd будет происходить в отдельной транзакции от модуля, из которого вы выполняете, и простое игнорирование сбоя xp_cmdshell должно позволить первичному Пакет, чтобы продолжить.

Вот некоторые идеи ...

0 голосов
/ 12 ноября 2009

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

...