Это правильный способ использования области транзакции:
У меня есть объект, который представляет часть вещи:
public class ThingPart
{
private DbProviderFactory connectionFactory;
public void SavePart()
{
using (TransactionScope ts = new TransactionScope()
{
///save the bits I want to be done in a single transaction
SavePartA();
SavePartB();
ts.Complete();
}
}
private void SavePartA()
{
using (Connection con = connectionFactory.CreateConnection()
{
con.Open();
Command command = con.CreateCommand();
...
command.ExecuteNonQuery();
}
}
private void SavePartB()
{
using (Connection con = connectionFactory.CreateConnection()
{
con.Open();
Command command = con.CreateCommand();
...
command.ExecuteNonQuery();
}
}
}
И то, что представляет вещь:
public class Thing
{
private DbProviderFactory connectionFactory;
public void SaveThing()
{
using (TransactionScope ts = new TransactionScope()
{
///save the bits I want to be done in a single transaction
SaveHeader();
foreach (ThingPart part in parts)
{
part.SavePart();
}
ts.Complete();
}
}
private void SaveHeader()
{
using (Connection con = connectionFactory.CreateConnection()
{
con.Open();
Command command = con.CreateCommand();
...
command.ExecuteNonQuery();
}
}
}
У меня также есть кое-что, что управляет многими вещами
public class ThingManager
{
public void SaveThings
{
using (TransactionScope ts = new TransactionScope)
{
foreach (Thing thing in things)
{
thing.SaveThing();
}
}
}
}
это мое понимание того, что:
- Соединения не будут новыми и будут повторно использоваться из пула каждый раз (при условии, что DbProvider поддерживает пул соединений и он включен)
- Транзакции будут такими, что если бы я просто вызвал
ThingPart.SavePart
(вне контекста любого другого класса), тогда части A и B либо были бы сохранены, либо ни одна из них не была бы.
- Если я позвоню
Thing.Save
(вне контекста любого другого класса), тогда Заголовок и все части будут сохранены или не сохранены, т.е. все будет происходить в одной транзакции
- Если я позвоню
ThingManager.SaveThings
, тогда все мои вещи будут сохранены или ничего не будет, т.е. все произойдет в одной транзакции.
- Если я изменю используемую реализацию
DbProviderFactory
, это не должно иметь значения
Верны ли мои предположения?
Не обращайте внимания на что-либо о структуре объектов или ответственности за постоянство, это пример, который поможет мне понять, как я должен делать вещи. Отчасти потому, что кажется, что он не работает, когда я пытаюсь заменить oracle на SqlLite в качестве фабрики провайдеров db, и мне интересно, где мне следует провести расследование.