Я собираюсь добавить еще один ответ здесь, потому что я придумал другой подход к моему предыдущему, а именно использовать языковые аспекты.
По сути, вы делаете:
std::locale::facet
. Небольшой недостаток в том, что вам понадобится модуль компиляции где-нибудь для хранения его идентификатора. Давайте назовем это MyPrettyVectorPrinter. Вы, вероятно, дадите ему лучшее имя, а также создадите его для пары и карты. std::has_facet< MyPrettyVectorPrinter >
std::use_facet< MyPrettyVectorPrinter >( os.getloc() )
operator<<
) предоставляет функции по умолчанию. Обратите внимание, что вы можете сделать то же самое для чтения вектора. Мне нравится этот метод, потому что вы можете использовать печать по умолчанию, но при этом можете использовать пользовательское переопределение.
Минусам нужна библиотека для вашего фасета, если она используется в нескольких проектах (поэтому не может быть только заголовками), а также тот факт, что вам нужно остерегаться затрат на создание нового объекта локали.
Я написал это как новое решение, а не изменяю другое, потому что я считаю, что оба подхода могут быть правильными, и вы выбираете.
Используйте класс TransactionScope следующим образом:
using (TransactionScope ts = new TransactionScope())
{
//all db code here
// if an error occurs jump out of the using block and it will dispose and rollback
ts.Complete();
}
Класс TransactionScope при необходимости автоматически преобразуется в распределенную транзакцию.
Как сказал Клетус, вам нужна какая-то двухфазная фиксация . Как говорится в статье, на практике это не всегда работает. Если вам нужно надежное решение, вы должны найти способ сериализации транзакций таким образом, чтобы вы могли выполнять их одну за другой и откатывать их по отдельности.
Поскольку это зависит от конкретного случая, в котором вы этого не делаете. Я не могу дать никаких подробностей, я не могу дать вам идеи, как это атаковать.
Если вы хотите выполнить транзакцию в нескольких экземплярах SQL Server, ознакомьтесь с документацией Координатора распределенных транзакций Microsoft
Использование transactionScope - вот ответ. Он работает даже с разными СУБД !!!