Я не привожу сюда какой-либо код, потому что я переписывал его так много раз за последние несколько дней, что на самом деле не стоит больше беспокоиться, поэтому я объясню свою проблему в общих чертах.
У меня есть приложение winforms, написанное на С# и подключенное к базе данных сервера sql. В некоторых частях моего приложения у меня может быть до 10 команд SQL, работающих с многочисленными таблицами в базе данных, и которые мне нужно содержать в одной транзакции, потому что это ситуация «все или ничего». Если какая-либо из 10 команд не удалась, я хочу, чтобы ни одна из команд не выполнялась.
К осложняющим факторам относятся:
- Каждая из 10 sqlcommands имеет несколько параметров
- Некоторые из sqlcommands используют INSERT, и мне нужно использовать сгенерированное сервером удостоверение в некоторых из последующих sqlcommands.
- Некоторые команды работают с одними и теми же данными, т. е. ранняя команда может ВСТАВИТЬ новый элемент в базу данных, а одна из более поздних команд sql попытается обновить ту же запись.
Любая помощь будет очень признательна, так как я не в своем уме с этой проблемой, потратив на нее большую часть недели, и чувствую, что был достигнут относительно небольшой прогресс.
РЕДАКТИРОВАТЬ:
Команды sql изначально были в разных классах и т. д., однако я подумал, что это может быть проблемой, поэтому я сильно переписал, и теперь ВСЕ команды sql находятся в одном и том же методе, хотя некоторые из команд sql написаны в другом месте и переданы обратно в основной метод.
На данный момент проблема заключается в том, что первая команда (INSERT) выполняется, но транзакция завершается ошибкой при выполнении второй команды, потому что она пытается сослаться на запись базы данных, созданную в первой команде.
Кроме того, я не могу использовать TransactionScope, потому что MSDTC в сети вызывает другие проблемы, поэтому мне нужно справиться с этим с помощью моего приложения и ADO.NET.
РЕДАКТИРОВАТЬ (НЕКОТОРЫЙ КОД)
Вот только первые две команды sql внутри транзакции:
string connectionString = aSystem.ConnectionString;
using (SqlConnection linkToDB = new SqlConnection(connectionString))
{
linkToDB.Open();
using (SqlTransaction transaction = linkToDB.BeginTransaction())
{
try
{
//...Case...//
cCase c = new cCase();
c.CaseType = cboCaseType.Text;
c.Occupation = txtOccupation.Text;
c.DateInstructed = txtDateInst.Text;
c.Status = "Live";
SqlCommand sqlSaveCase = c.SaveSqlCom();
sqlSaveCase.Connection = linkToDB;
sqlSaveCase.Transaction = transaction;
c.SetCaseNo = sqlSaveCase.ExecuteNonQuery().ToString();
//...IP Link...//
string strIPID = cboIPAddress.SelectedValue.ToString();
SqlCommand sqlNewIPLink = cIPID.NewIPLinkSqlCom(strIPID,c.CaseNo,txtIPRef.Text);
sqlNewIPLink.Connection = linkToDB;
sqlNewIPLink.Transaction = transaction;
sqlNewIPLink.ExecuteNonQuery(); //...fails here...//
//...an additional 8 sql commands follow...//
ПРОБЛЕМА
Команда sqlSaveCase ВСТАВЛЯЕТ новый случай в tblCases, но когда вторая команда sqlNewIPLink пытается использовать идентификатор, созданный первой, она генерирует ошибку внешнего ключа, как будто она не видит вновь созданный случай из первой команды.
SqlTransaction
? Возможно, попробуйте разделить это на несколько вопросов, каждый из которых касается конкретной проблемы, которую можно легко продемонстрировать на простом примере кода. - person Nikola Anusev   schedule 28.07.2012