基本上我在字典中迭代一些项目,我试图在C#中使用TransactionScope
从数据库中删除一些记录。我调用包含在TransactionScope
内的存储过程。现在,当我的存储过程正在执行时,我正在对我的主存储过程中的其他存储过程进行多次调用。
当我解雇存储过程时,我使用严重级为10的Raiserror方法发送进度日志。
到目前为止一切都很好。它从存储过程发送所有raiserror消息。
我的问题是,如果存储过程中发生任何异常,那么它将进入存储过程内的catch方法。但是在C#方面,它并没有进入catch,而是将其视为正常流程,并继续下一个要删除的集合项目。
在C#端,我使用的是SqlInfoMessageEventHandler
,它会触发我写的SqlInfoMessage
。我想我在实施这个活动时犯了错误。
现在当我评论SqlInfoMessageEventHandler
时,C#中的catch工作正常,它会按预期回滚所有更改。
我的代码如下。
public void Purge(string keyName, string[] keyValues, ILog logger)
{
try
{
currentKeyName = keyName;
for (var i = 0; i < keyValues.Length; i++)
{
currentKeyValue = keyValues[i];
using (adoConnection = new SqlConnection())
{
using (SqlCommand adoCommand = new SqlCommand())
{
adoCommand.CommandText = "procName";
adoCommand.CommandType = CommandType.StoredProcedure;
// Set up the parameters to be substituted into the SQL
// if app number then set the currentKeyValue and set empty for othe params
SqlParameter[] sqlParam = new SqlParameter[]
{
//fill up values for all params
};
adoCommand.Parameters.AddRange(sqlParam);
adoConnection.ConnectionString = connectionString;
adoConnection.InfoMessage += new SqlInfoMessageEventHandler(SQLInfoMessage);
adoConnection.FireInfoMessageEventOnUserErrors = true;
adoConnection.Open();
adoCommand.Connection = adoConnection;
logger.Info(String.Format("-------------------------------------------------------------------------------------------------------"));
logger.Info(String.Format("started for {0}: {1}", currentKeyName, currentKeyValue));
adoCommand.ExecuteNonQuery();
logger.Info(String.Format("finished successfully for {0}: {1}", currentKeyName, currentKeyValue));
logger.Info(String.Format("-------------------------------------------------------------------------------------------------------"));
}
}
}
}
catch (SqlException ex)
{
if (logger.IsErrorEnabled) logger.Error(FormatSqlExceptionMessage(ex));
}
catch (Exception ex)
{
if (logger.IsErrorEnabled)
logger.Error("Application Error.", ex);
}
finally
{
if (logger.IsDebugEnabled)
logger.Debug(String.Format("Closing Connection for: {0}", currentKeyValue));
}
}
// Sql info method
private void SQLInfoMessage(object sender, SqlInfoMessageEventArgs args)
{
sleepTime = 100;
if (args.Errors.Count > 0)
{
foreach (SqlError info in args.Errors)
{
if (info.Class > 9) // Severity
{
if (logger.IsErrorEnabled)
logger.Error(String.Format("SQL: {0}", info.Message));
}
else
{
if (logger.IsInfoEnabled)
logger.Info(String.Format("SQL: {0}", info.Message));
}
}
}
else
{
if (logger.IsInfoEnabled)
logger.Info(String.Format("SQL: {0}", args.Message));
}
}
// TransactionScope Method
foreach (KeyValuePair<string, List<string>> purgeRecord in purgeDictionary)
{
foreach (string keyValue in purgeRecord.Value)
{
try
{
using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
{
Purge(purgeRecord.Key, new string[] { keyValue }, Logger);
transactionScope.Complete();
}
}
catch (SqlException ex)
{
Logger.Error("Error occurred In InitiatePurgePendingProcess()" + ex.Message + ex.InnerException);
}
}
}
答案 0 :(得分:1)
如果要引发SqlException,请将FireInfoMessageEventOnUserErrors
更改为false
(默认值)。如果指定了true,则不会引发SqlException,而是使用错误调用消息处理程序。
adoConnection.FireInfoMessageEventOnUserErrors = false;