Em alguns casos é muito importante controlar os objetos Persist em transações, garantindo desta forma que possamos cancelar um processo "distribuído" em várias etapas, retornando todas as etapas ao seu ponto inicial.

Para realizar tal feito, basta utilizar o método UseCommand() que todo os objetos Persist herdam para referenciar uma mesma instância do Command (criado externamente), além de garantir que todos os objetos do processo sejam salvos com a propriedade IsDone setada para false, exceto o úlitmo objeto, pois este será o responsável por comitar os demais.

Veja abaixo um exemplo.

var state = new State();

// esta é a primeira metade do segredo
state.UseCommand(command);

state.Name = "Paraíba";
state.Description = "Estado mais bonito do mundo";
state.Save();

for(var i = 0;i < CitiesToSave.Count; i++)
{

var city = new City();

// repare que fazemos o mesmo para todos os objetos
city.UseCommand(command);

city.StateId = state.StateId;
city.Description = CitiesToSave[i].Description;

// Esta é a segunda metade do segredo.
// Quando for a última cidade da lista o IsDone não será
// setado para false dessa forma quando a última cidade
// executar o método Save irá comitar a transação de todos
// os outros objetos.
if(i != CitiesToSave.Count - 1)
city.IsDone = false;

city.Save();

}


Uma implementação possível sintáticamente, porém ERRADA, pois não terá o mesmo efeito. É implementar os métodos BeginTransaction, Commit e RollBack, direto no Command que é passado por referência.

Apesar de ser possível, esta aplicação não surte efeito, pois cada objeto Persist possui testes baseados no IsDone para executar o Commit de sua transação. Então o exemplo abaixo mostra um exemplo que não funcionará.

try
{

command.BeginTransaction();

var state = new State();
state.UseCommand(command);
state.IsDone = false;

state.Name = "Paraíba";
state.Description = "Estado mais bonito do mundo";
state.Save();

for(var i = 0;i < CitiesToSave.Count; i++)
{

var city = new City();
city.UseCommand(command);
city.StateId = state.StateId;
city.Description = CitiesToSave[i].Description;
city.Save();

}

command.Commit();

}
catch (Exception)
{

command.RollBack();

}


Esta estrutura só deve ser usada em códigos a estrutura descrita neste outro artigo. Novamente, a sintaxe é super simples. Se tiver alguma dúvida, mande sua pergunta no fórum.

Last edited Mar 9, 2010 at 2:45 PM by ivanpaulovich, version 1

Comments

No comments yet.