.net TransactionScope Exception - c#

My Code something like this
try
{
using (TransactionScope iScope = new TransactionScope())
{
try
{
isInsertSuccess = InsertProfile(account);
}
catch (Exception ex)
{
throw;
}
if (isInsertSuccess)
{
iScope.Complete();
retValue = true;
}
}
}
catch (TransactionAbortedException tax)
{
throw;
}
catch (Exception ex)
{
throw;
}
Now what happen is that even if my value is TRUE a TransactionAbortedException Exception occurs randomly, but data get's inserted/updated in DB.
Any idea what went wrong?

As the TransactionAbortedException documentation says,
This exception is also thrown when an attempt is made
to commit the transaction and the
transaction aborts.
This is why you see the exception even after calling Transaction.Complete: the Complete method is not the same thing as Commit:
calling this method [TransactionScope.Complete] does not guarantee
a commit of the transaction. It is
merely a way of informing the
transaction manager of your status
The transaction isn't committed until you exit the using statement: see the CommittableTransaction.Commit documentation for details. At that point any actions participating in the transaction may vote to abort the transaction and you'll get a TransactionAbortedException.
To debug the underlying problem you need to analyze the exception details and stack trace. As Mark noted in a comment, it may well be caused by a deadlock or another interaction with other database processes.

Related

Set an exception breakpoint for all exceptions except task cancellation

I want to set a breakpoint in my C#/Xamarin Studio project that breaks on all exceptions, EXCEPT those that have to do with task cancellation. Is that possible?
You should use separate catch for CancellationException
try
{
//do your stuff here
}
catch(CancellationException ex)
{
//behave cancellation
}
catch(Exception ex)
{
//Here handle other exceptions
//Also you can put break point here
}
If you know your entry point exactly, you could write a code like this:
try
{
....
}
catch (CancellationException)
{
throw;
}
catch (Exception ex)
{
//otherwise handle this exception
}
If not, you could catch at application domain level using the event
ApplicationDomain.UnhandledException. More details here: http://developer.xamarin.com/api/event/System.AppDomain.UnhandledException/
I think it is possible. You may add catching all exceptions listening to System.Exception. Add the condition and check the type of exception in order to skip task cancelled exceptions. Exception in the local scope is available as $exception, so the condition will look like !($exception is System.Threading.Tasks.TaskCanceledException)

Is Rollback automatic in a "Using" scope with C# SQL Server calls?

When you create 'using' blocks for your SQL Connection, Transaction, and Command, it is well known that the connection, transaction, or command that the using block is associated with is disposed on its own properly after you leave the using block.
If an exception occurs in one of these blocks though, for instance in the command block - Would the transaction be rolled back on its own, or do developers need to do a try catch inside of the command 'using' block, and add a rollback transaction statement in the catch for this try?
The transaction is rolled back automatically as long as you haven't successfully called Commit. So your using blocks can look something like this, and the transaction will be rolled back if an exception is thrown before the Commit.
using (IDbConnection connection = ...)
{
connection.Open();
using (IDbTransaction transaction = connection.BeginTransaction())
{
using (IDbCommand command = ...)
{
command.Connection = connection;
command.Transaction = transaction;
...
}
...
transaction.Commit();
}
}
It's not guaranteed to get disposed. The Dispose(bool) method of the SqlTransaction will in fact roll it back conditionally:
// System.Data.SqlClient.SqlTransaction
protected override void Dispose(bool disposing)
{
if (disposing)
{
SNIHandle target = null;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
target = SqlInternalConnection.GetBestEffortCleanupTarget(this._connection);
if (!this.IsZombied && !this.IsYukonPartialZombie)
{
this._internalTransaction.Dispose();
}
}
catch (OutOfMemoryException e)
{
this._connection.Abort(e);
throw;
}
catch (StackOverflowException e2)
{
this._connection.Abort(e2);
throw;
}
catch (ThreadAbortException e3)
{
this._connection.Abort(e3);
SqlInternalConnection.BestEffortCleanup(target);
throw;
}
}
base.Dispose(disposing);
}
and if you notice, it would only happen if this._internalTransaction.Dispose(); got called. The problem here is that if GetBestEffortCleanupTarget throws an exception it won't get cleaned up.
In your case, as long as an exception isn't thrown as already stated, you will fall into the category of being Zombied and so it will then actually issue a Rollback call in the _internalTransaction.Dispose() call.
Finally, if this is called with false it will most certainly not get disposed.
Now, unless I'm really missing something here I'm a bit appalled at how fragile this code is.
An interesting note is that I think the MSDN documentation is actually wrong because it states, for the Rollback() method:
The transaction can only be rolled back from a pending state (after BeginTransaction has been called, but before Commit is called). The transaction is rolled back in the event it is disposed before Commit or Rollback is called.

C# oracle : catch all exceptions relative to connectivity?

In c#, can I catch all errors about (non) connectivity to an Oracle database?
I don't want to catch error about badly written query but only errors like No listener, connection lost...
If queries are badly written (or table are missing) then this is my fault.
But if Oracle or the network is down then this should be held by another department.
Write your code in which you build the connection in a try catch part:
try
{
BuildConnection(connectionString);
}
catch (OracleException ex)
{
//Connectivity Error
}
Errors between ORA-12150 to ORA-12236 are related to connection errors. A few examples:
ORA-12154: TNS:could not resolve the connect identifier specified
ORA-12152: TNS:unable to send break message
ORA-12157: TNS:internal network communication error
Please refer to https://docs.oracle.com/cd/E11882_01/server.112/e17766/net12150.htm
Simple answer for this Type of problem is Use Try Catch Block like
try
{
// your code
}
catch (OracleException ex)
{
}
MSDN HELP
Sure - you can catch specific exception types, or if they're all the same exception type, you can catch it, check to see if it's a specific type, and re-throw ones you don't want to handle. Not having your syntax, here's an example...
try
{
// your Oracle code
}
catch (OracleException ex)
{
if (ex.Message == "Something you don't want caught")
{
throw;
}
else
{
// handle
}
}
errors like No listener, connection lost are still caught in System.Data.SqlClient.SqlException, however, you may inspect ErrorCode and Errors to handle different situations accordingly, say, not listener or connection lost etc.
MSDN does not seem to document all possible errors, however, you may write a few unit tests or integration tests to learn what appear in ErrorCode and Errors, then write error handlers in production codes accordingly.
OracleException contains only ErrorCode not Errors. So you may be using switch(e.ErrorCode) to handle different situations.
I observed that each time a network exception occurs, then a SocketException can be found in inner exceptions.
I also observed that when a network exception occurs, the first inner exception is of type «OracleInternal.Network.NetworkException» but unfortunately, this class is internal...
Based on this observations, I would code something like this:
public void RunQuery()
{
try
{
var con = new OracleConnection("some connection string");
con.Open();
var cmd = con.CreateCommand();
// ...
cmd.ExecuteNonQuery();
}
catch (Exception ex) when (IsNetworkException(ex))
{
// Here, a network exception occurred
}
catch (Exception ex)
{
// Here, an other exception occurred
}
}
private static bool IsNetworkException(Exception ex)
{
var exTmp = ex;
while (exTmp != null)
{
if (exTmp is SocketException)
return true;
exTmp = exTmp.InnerException;
}
return false;
}

Try Catch handled at top of process

if I do this:
try
{
//code
}
catch (Exception)
{
throw;
}
Does the Exception go up with all its information?
The idea is to handle errors at the top of the app. There I'd execute some SQL sp to fill the admin's table so he's aware of exceptions.
I want to store Exception.Message and the source (method, function, whatever..) of the exception. But I don't know how to refer to "where" the exception happened. Is it Exception.Source? Exception.TargetSite?
Thanks.
The type of Exception will tell you what kind of exception it is (IndexOutOfRangeException, SqlException, etc) which you would react too accordingly:
try
{
//code
}
catch (SqlException ex)
{
// Handle code
}
catch (IndexOutOfRangeException ex)
{
// Handle code
}
catch (Exception ex)
{
// Handle code
}
As to where it is happening... you should be enclosing exception-prone areas with a try catch and not large code chunks. This way you will know where the exception derives from.
The Short answer is yes: just calling throw passes everthing regarding the exception up.
throw ex resets the stack trace (so your errors would appear to originate from HandleException)
throw doesn't - the original offender would be preserved.
(quoted from Mark Gravell)

Continue after try-catch-finally

This might sound like a weird question but I don't get it...
Let's say I have an application which connects to a server to do some stuff. This connect might fail and throw an exception which I can catch.
try {
Client.connect();
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
However, in case that the connect is succcesful the application shall continue...
try {
Client.connect();
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
// Talk to the server...
The "server talking" however is executed in any case. It doesn't matter if the exception occured or not.
How can I make sure that the "server talking" is only executed if the connect was successful? Do I have to move all of the following code inside the trystatement? What is a clean way to program such a behavior?
"Talk to the server" should happen in the try block, right after
Client.connect();
The easiest way is to just set a boolean. But there are many many many ways to deal with this.
bool connectionError = false;
try {
// connect
} catch (...) {
connectionError = true;
} finally {
// whatever
}
if (!connectionError) {
// talk to server.
}
Have another variable like clientConnected and set it to true right after Client.Connect(). Then outside the try-catch check for clientConnected before talking to the server.
Avoid doing everything in a single try-catch. You should use separate try-catch blocks for different actions that might throw exceptions, and catch specific exceptions as much as possible.
Typically you use try...catch statements for those statements which you expect to throw an Exception. Try...Catch defines its own scope, so you should declare any variables outside of the Try...Catch block (at least, those variables that you want to use outside of it).
If you want to know if an exception was thrown, then define the Exception variable above the Try...Catch. You can then examine it to determine if it is Null or not.
System.Exception ex;
try {
Client.connect();
} catch (ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
if (ex != null){ ... }
// Talk to the server...
You could log an event and then call some code to either try again or to cancel... or whatever you need to do.
Use some type of flag variable to indicate whether server is connected or not. If your method is returning a boolean variable then also it is ok.
int flag=0;
while(flag==0){
try {
Client.connect();
flag=1;
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
}
//If server connects code

Categories

Resources