Explorar el Código

** Fixes Bug#381151
* SqlCommand.cs: Handle exceptions sanely and do not close
connection on TdsTimeoutException.


svn path=/trunk/mcs/; revision=101411

Veerapuram Varadhan hace 17 años
padre
commit
4f724ba9eb

+ 6 - 0
mcs/class/System.Data/System.Data.SqlClient/ChangeLog

@@ -1,3 +1,9 @@
+2008-04-22  Veerapuram Varadhan  <[email protected]>
+
+	** Fixes Bug#381151
+	* SqlCommand.cs: Handle exceptions sanely and do not close
+	connection on TdsTimeoutException.
+	
 2008-04-21  Gert Driesen  <[email protected]>
 
 	* SqlBulkCopyColumnMappingCollection.cs: Changed argument names to

+ 30 - 34
mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs

@@ -380,6 +380,8 @@ namespace System.Data.SqlClient {
 
 			try {
 				Connection.Tds.ExecProc (sql, localParameters.MetaParameters, 0, true);
+			} catch (TdsTimeoutException ex) {
+				throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
 			} catch (TdsInternalException ex) {
 				Connection.Close ();
 				throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
@@ -423,6 +425,7 @@ namespace System.Data.SqlClient {
 					sql1.Append ("SET FMTONLY ON;");
 					sql2.Append ("SET FMTONLY OFF;");
 				}
+				
 				switch (CommandType) {
 				case CommandType.StoredProcedure:
 					try {
@@ -431,6 +434,12 @@ namespace System.Data.SqlClient {
 						Connection.Tds.ExecProc (CommandText, parms, CommandTimeout, wantResults);
 						if (keyInfo || schemaOnly)
 							Connection.Tds.Execute (sql2.ToString ());
+					} catch (TdsTimeoutException ex) {
+						// If it is a timeout exception there can be many reasons:
+						// 1) Network is down/server is down/not reachable
+						// 2) Somebody has an exclusive lock on Table/DB
+						// In any of these cases, don't close the connection. Let the user do it
+						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
 					} catch (TdsInternalException ex) {
 						Connection.Close ();
 						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
@@ -445,6 +454,8 @@ namespace System.Data.SqlClient {
 					}
 					try {
 						Connection.Tds.Execute (sql, parms, CommandTimeout, wantResults);
+					} catch (TdsTimeoutException ex) {
+						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
 					} catch (TdsInternalException ex) {
 						Connection.Close ();
 						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
@@ -455,6 +466,8 @@ namespace System.Data.SqlClient {
 			else {
 				try {
 					Connection.Tds.ExecPrepared (preparedStatement, parms, CommandTimeout, wantResults);
+				} catch (TdsTimeoutException ex) {
+						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
 				} catch (TdsInternalException ex) {
 					Connection.Close ();
 					throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
@@ -492,27 +505,12 @@ namespace System.Data.SqlClient {
 		public new SqlDataReader ExecuteReader (CommandBehavior behavior)
 		{
 			ValidateCommand ("ExecuteReader");
-			try {
-				this.behavior = behavior;
-				if ((behavior & CommandBehavior.SequentialAccess) != 0)
-					Tds.SequentialAccess = true;
-				Execute (behavior, true);
-				Connection.DataReader = new SqlDataReader (this);
-			} catch (TdsTimeoutException e) {
-				// if behavior is closeconnection, even if it throws exception
-				// the connection has to be closed.
-				if ((behavior & CommandBehavior.CloseConnection) != 0)
-					Connection.Close ();
-				throw SqlException.FromTdsInternalException ((TdsInternalException) e);
-			} catch (SqlException) {
-				// if behavior is closeconnection, even if it throws exception
-				// the connection has to be closed.
-				if ((behavior & CommandBehavior.CloseConnection) != 0)
-					Connection.Close ();
-
-				throw;
-			}
-
+			this.behavior = behavior;
+			if ((behavior & CommandBehavior.SequentialAccess) != 0)
+				Tds.SequentialAccess = true;
+			Execute (behavior, true);
+			Connection.DataReader = new SqlDataReader (this);
+			
 			return Connection.DataReader;
 		}
 
@@ -526,12 +524,7 @@ namespace System.Data.SqlClient {
 				object result = null;
 				ValidateCommand ("ExecuteScalar");
 				behavior = CommandBehavior.Default;
-				try {
-					Execute (CommandBehavior.Default, true);
-				}
-				catch (TdsTimeoutException e) {
-					throw SqlException.FromTdsInternalException ((TdsInternalException) e);
-				}
+				Execute (CommandBehavior.Default, true);
 
 				try {
 					if (Connection.Tds.NextResult () && Connection.Tds.NextRow ())
@@ -541,6 +534,8 @@ namespace System.Data.SqlClient {
 						Connection.Tds.SkipToEnd ();
 						GetOutputParameters ();
 					}
+				} catch (TdsTimeoutException ex) {
+					throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
 				} catch (TdsInternalException ex) {
 					Connection.Close ();
 					throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
@@ -740,7 +735,6 @@ namespace System.Data.SqlClient {
 					sql1.Append ("SET FMTONLY ON;");
 					sql2.Append ("SET FMTONLY OFF;");
 				}
-
 				switch (CommandType) {
 				case CommandType.StoredProcedure:
 					string prolog = "";
@@ -757,6 +751,8 @@ namespace System.Data.SqlClient {
 										      parms,
 										      callback,
 										      state);
+					} catch (TdsTimeoutException ex) {
+						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
 					} catch (TdsInternalException ex) {
 						Connection.Close ();
 						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
@@ -769,6 +765,8 @@ namespace System.Data.SqlClient {
 							ar = Connection.Tds.BeginExecuteQuery (sql, parms, callback, state);
 						else
 							ar = Connection.Tds.BeginExecuteNonQuery (sql, parms, callback, state);
+					} catch (TdsTimeoutException ex) {
+						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
 					} catch (TdsInternalException ex) {
 						Connection.Close ();
 						throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
@@ -779,6 +777,8 @@ namespace System.Data.SqlClient {
 			else {
 				try {
 					Connection.Tds.ExecPrepared (preparedStatement, parms, CommandTimeout, wantResults);
+				} catch (TdsTimeoutException ex) {
+					throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
 				} catch (TdsInternalException ex) {
 					Connection.Close ();
 					throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
@@ -855,17 +855,13 @@ namespace System.Data.SqlClient {
 			try {
 				reader = new SqlDataReader (this);
 			} catch (TdsTimeoutException e) {
-				// if behavior is closeconnection, even if it throws exception
-				// the connection has to be closed.
-				if ((behavior & CommandBehavior.CloseConnection) != 0)
-					Connection.Close ();
 				throw SqlException.FromTdsInternalException ((TdsInternalException) e);
-			} catch (SqlException) {
+			} catch (TdsInternalException e) {
 				// if behavior is closeconnection, even if it throws exception
 				// the connection has to be closed.
 				if ((behavior & CommandBehavior.CloseConnection) != 0)
 					Connection.Close ();
-				throw;
+				throw SqlException.FromTdsInternalException ((TdsInternalException) e);
 			}
 
 			((SqlAsyncResult) asyncResult).Ended = true;