Вам необходимо открыть транзакцию по соединению с клиента (например, приложения C #), а не из базы данных.Псевдокод:
- открытое соединение
- открытая транзакция
- сохранение данных заказа
- для элемента = 1 .. n
- совершить транзакцию
- закрыть соединение
Вот пример от Microsoft, слегка измененный для иллюстрации вашего конкретного случая: http://msdn.microsoft.com/en-us/library/2k2hy99x(v=VS.100).aspx
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// Start a local transaction.
SqlTransaction sqlTran = connection.BeginTransaction();
// Enlist a command in the current transaction.
SqlCommand command = connection.CreateCommand();
command.Transaction = sqlTran;
try
{
// Execute two separate commands.
command.CommandText =
"INSERT INTO Order ...";
command.ExecuteNonQuery();
// ПРИМЕЧАНИЕ: ваша команда, вероятно, должна вернуть идентификатор нового ордера, чтобы вы могли передать его вставке OrderItem ниже;в этом случае вы можете использовать command.ExecuteScalar () или command.ExecuteReader () для возврата идентификатора;В простейшем сценарии вы могли бы выполнить другую команду с «SELECT @@ SCOPE_IDENTITY ()» в качестве текста, но гораздо лучше написать хранимую процедуру для обработки вставки (и вернуть идентификатор)
foreach (var item in order.Items)
{
command.CommandText = "INSERT INTO OrderItem ... ";
command.ExecuteNonQuery();
}
// Commit the transaction.
sqlTran.Commit();
}
catch (Exception ex)
{
// Handle the exception if the transaction fails to commit.
Console.WriteLine(ex.Message);
try
{
// Attempt to roll back the transaction.
sqlTran.Rollback();
}
catch (Exception exRollback)
{
// Throws an InvalidOperationException if the connection
// is closed or the transaction has already been rolled
// back on the server.
Console.WriteLine(exRollback.Message);
}
}
}