Вложенные транзакции
Одной из замечательных возможностей, которые поддерживает IBProvider - это использование вложенных транзакций. Уровень вложенности транзакций не ограничен. Для того чтобы включить использование вложенных транзакций, необходимо установить свойство инициализации nested_trans = true. Следующий пример демонстрирует применение вложенных транзакций:
public void InternalTransactionTest() { OleDbConnectionStringBuilder builder = ConnectionProvider.GetConnectionStringBuilderFromUDL(); //включить вложенные транзакции
builder.Add("nested_trans", true);
OleDbConnection con1 = new OleDbConnection(builder.ToString()); con1.Open();
//основная транзакция
OleDbTransaction trans = con1.BeginTransaction();
//добавить новую запись
OleDbCommand cmd_insert = new OleDbCommand( "insert into country (country,currency) values (:country,:currency)", con1, trans);
cmd_insert.Parameters.AddWithValue(":country", "Russia"); cmd_insert.Parameters.AddWithValue(":currency", "Ruble"); Assert.AreEqual(1, cmd_insert.ExecuteNonQuery());
//запустить вложенную транзакцию
OleDbTransaction internal_transaction = trans.Begin();
//запустить вложенную транзакцию внутри вложенной
OleDbTransaction internal_transaction2 = internal_transaction.Begin();
//удалить запись во вложенно транзакции третьего уровня
OleDbCommand cmd_delete = new OleDbCommand( "delete from country where country=?", con1, internal_transaction2); cmd_delete.Parameters.AddWithValue("?", "Russia"); Assert.AreEqual(1, cmd_delete.ExecuteNonQuery());
//откатить вложенную транзакцию третьего уровня
internal_transaction2.Rollback();
//проверить что запись не была удалена в тразакции второго уровня
OleDbCommand cmd_check = new OleDbCommand( "select count(*) from country where country=?", con1, internal_transaction);
cmd_check.Parameters.AddWithValue("?", "Russia"); Assert.AreEqual (1, cmd_check.ExecuteScalar());
//удалить запись
cmd_delete.Transaction = internal_transaction; Assert.AreEqual(1, cmd_delete.ExecuteNonQuery());
//зафиксировать изменения
internal_transaction.Commit();
//проверить в основной транзакции что запись удалена из БД
cmd_check.Transaction = trans; Assert.AreEqual(0, cmd_check.ExecuteScalar());
trans.Commit(); con1.Close(); }