Goku, since your question makes use of Linq to SQL, then I will consider only transactions involving Database and will disregard transactions with instated objects.
So, to get the good use of a Transaction, we must respect the ACID.:
Atomicity: A transaction must be an atomic unit of work; either all your data modifications are executed or
none of them is executed.¹
Since the transactions must be atomic and by good practice the methods must have a single responsibility, then it is interesting that only one Transaction per method.
Consistency: When completed, a transaction should leave all data in a consistent state. In a relational database,
all rules shall be applied to modifications of the transaction to
maintain full data integrity. All data structures
internal, such as B-tree indices or double lists
linked, must be correct at the end of the transaction.¹
Isolation: Modifications made by simultaneous transactions should be isolated from modifications made by any other transaction
simultaneous. A transaction recognizes the data in the state they were in
before another simultaneous transaction has modified or recognized the
data after the second transaction has been completed, but not
recognizes an intermediate state. This is called serializability
because it results in the ability to reload the initial data and
forward a series of transactions so that the data obtained
are in the same state as they were after the transactions
originals were executed.¹
Durability: After a transaction has been completed, its effects remain permanently on the system. Modifications persist
even in the case of a system crash.¹
So with this in mind, then perhaps your method would make better use of Transactionscope if it were implemented as follows.:
ModeloColDataContext dm = DataContextFactory.GetContext(usuario);
{
if (documento > 0)
{
try
{
using (TransactionScope tr = new TransactionScope())
{
var updateDocumento = dm.ExecuteQuery<String>(@"
UPDATE TABELA_DOCUMENTOS
SET CLIENTE = {0}
WHERE CLIENTE = {1} AND DOCUMENTO = {2}
", clienteNovo, clienteAtual, documento);
if (updateDocumento == valorEsperado)
{
// realiza mais algunas operações no Banco
// note, caso o updateDocumento não tenha o valor esperado ou ocorra algum erro durante as consultas posteriores, o "UPDATE TABELA_DOCUMENTOS..." será desfeito.
tr.Complete();
}
}
}
catch (Exception err)
{
//realiza algum tratamento para o erro
}
}
}
However, if your Dmls commands are completely independent and must be searched regardless of the outcome of the others (which is what is happening in your example), then there is no need to use Transactionscope, after all its operations need not be Atomic.
P.S.: Another point that I found strange in your example was the non-sparameterization of the query. By parameterizing you gain in security (avoids SQL injection) and performance (the database can cache the query execution plan).
¹ - Transactions (Data Bank Mechanism)
I can’t stop to make a good example right now, so I’m just going to put a comment on that link, I think here you can understand cool, sorry I didn’t create a good answer.
– Ricardo
@Ricardo, if it were in Portuguese it would be cool.
– Marco Souza
@Gokussjgod, are you creating a Transaction by command? or is this just an example?
– Tobias Mesquita
@Tobymosque, this was already in a class I’m giving maintenance..
– Marco Souza