First of all, I find the structure of your code sample quite confusing. When using a TransactionScope, you typically don't write statements after scope.Complete() or scope.Dispose() have been called. Moreover, the using statement disposes the scope for you, so IMHO you should not call scope.Dispose() explicitly if you can help it. In other words: try to refactor your code so that it looks something like this:
private void PerformTransactionalOperation()
{
Log.Write("Starting operation.");
try
{
using (var scope = CreateTransactionScope())
{
if (PerformTransactionalOperationCore())
{
Log.Write("Committing...");
scope.Complete();
Log.Write("Committed");
}
else
{
Log.Write("Operation aborted.");
}
}
}
catch (Exception exception)
{
Log.Write("Operation failed: " + exception.Message);
throw;
}
}
private bool PerformTransactionalOperationCore()
{
// Perform operations and return status...
}
Secondly, the transaction-scope was specifically designed to complete only when no exception was raised, so your design might be improved by letting the PerformTransactionalOperationCore throw a specific exception instead of returning false.
Then on the logging matter: make sure your logging framework does not participate in the same transaction as the operation your are logging about. You can do this by always logging within a TransactionScope with option Suppress (that is, when you are logging to a resource that is transaction-aware in the first place, like a database). And by the way, why are you writing log-statements by instantiating new LogProcess-instances?