Я занимаюсь разработкой бизнес-объектов на C #. Каждый объект имеет возможность сохранять себя в связанной базе данных, например, такой (каждый объект):
public void Save()
{
//Collect object attributes and convert to SQLParameters
//Add SQL Parameters to SQL command and BeginTrans
//Execute, if No Errors, commit, otherwise rollback
}
Я начал реализацию наследования / родительской дочерней части, и я не знаю, как структурировать родительский объектФункция Save () с внутренними дочерними объектами, потому что:
- Каждый дочерний объект имеет свой собственный метод Save (), в котором есть свои собственные Connection, SQL-команда, BeginTrans, логика параметров и логика отката и т. Д.
- Каждый вызов Object.Save () является определенной хранимой процедурой для этого типа объекта / базы данных.
- НАИБОЛЕЕ ВАЖНО: Я хочу, чтобы ПОЛНОЕ СОХРАНЕНИЕ откатывалось, если какой-либо дочерний объект Сохранить сбой.
Например:
Если у объекта "Клиент" есть дочерние объекты "CustomerInfo", "Account" и "Dependents".
Когда выполняется Customer.Save, если сохранение для дочерних объектов «CustomerInfo» и «Account» выполнено успешно, но затем сохранение для дочернего объекта «Dependents FAIL», тогда я хочупредыдущие сохранения сохраняются для отката до вызывающего родительского объекта Customer.
Каков наилучший способ сделать это?
Я хотел бы сохранить логику для сохранения (форматирование, выполнение и откат параметров), инкапсулированных в каждом объекте, т.е.
Примерно так:
public void ParentSave()
{
Begin Transaction
Try
{
//For each CHILD Object
//ChildObject.Save()
}
Catch(Save Fail)
{
//Rollback all executed saves/transaction(s)
}
IF(Success)
{
//Save parent
Commit parent/overall transaction
}
}
Я знаю, что могу использовать область действия «транзакция», но я не уверен, как ее структурироватьили если бы у меня были "вложенные" области транзакций. Я никогда раньше не использовал транзакцию Scope. Я знаю, что Transaction работает с вложенными транзакциями Begin / Commit (истинное принятие не происходит до тех пор, пока счетчик begin trans не достигнет 1), но работает ли оно для вложенных транзакций, используя их объект Connection / SQLCommand?
Относительно «объема транзакции»: если каждый объект имеет свое сохранение в своей собственной инкапсулированной функции (каждый объект save () запускает свое собственное соединение, команду SQL, выполняет Begin / commit, выполняет и закрывает объект команды SQL) **
Я НЕ хочу писать конкретную хранимую процедуру для каждой родительской / дочерней схемы (т. Е. Иметь сохраненный процесс для каждого варианта родительских / дочерних объектов).
Если бы это было НЕОБХОДИМО, я мог бы написать логику для каждого объекта, чтобы получить свою собственную информацию SQLParameters / command, чтобы вызывающий родительский объект мог объединить их и выполнить их в одной большой поэтапной транзакции, но я бы не стал.
Если мне нужно написать поэтапную транзакцию, должен ли я использовать «Sql SavePoints»? Почему, почему нет? Я предполагаю НЕТ, как будто есть какие-либо ошибки, я откатываю ВСЮ вещь назад.
Я мог бы передать объект соединения, если необходимо, чтобы "цепочка" цепочки сохранялась этим родительским объектом.