对于已经存在于catch子句中的SqlTransaction RollBack,实现错误处理的最佳方法是什么?我的代码大致如下:
using (SqlConnection objSqlConn = new SqlConnection(connStr)) {
objSqlConn.Open();
using (SqlTransaction objSqlTrans = objSqlConn.BeginTransaction()) {
try {
// code
// more code
// and more code
}
catch (Exception ex) {
// What happens if RollBack() has an exception?
objSqlTrans.Rollback();
throw ex;
}
}
}我认为我的应用程序在try块中有一个异常,然后在catch块中捕获该异常,然后尝试RollBack。但是,我看到的错误说明了一个SqlTransaction.ZombieCheck(),这让我怀疑RollBack()本身是否也抛出了异常。那么,我是否需要在RollBack()中实现某种类型的错误处理?我如何做到这一点,并设法保持异常,即将执行放在catch块的首要位置?
编辑-我所有的代码:
using (SqlConnection objSqlConn = new SqlConnection(connStr)) {
objSqlConn.Open();
// Begin Transaction
using (SqlTransaction objSqlTrans = objSqlConn.BeginTransaction()) {
try {
// Create file in db (which in turn creates it on disk according to where the
// ...FileStream points)
SqlCommand objSqlCmd = new SqlCommand("usp_FileAdd", objSqlConn, objSqlTrans);
objSqlCmd.CommandType = CommandType.StoredProcedure;
// Sql parameter - report name
SqlParameter objSqlParam1 = new SqlParameter("@ObjectID", SqlDbType.Int);
objSqlParam1.Value = objID;
// Sql out parameter - returns the file path
SqlParameter objSqlParamOutput = new SqlParameter("@filepath", SqlDbType.VarChar, -1);
objSqlParamOutput.Direction = ParameterDirection.Output;
// Add Sql parameters to command obj
objSqlCmd.Parameters.Add(objSqlParam1);
objSqlCmd.Parameters.Add(objSqlParamOutput);
// Execute command object
objSqlCmd.ExecuteNonQuery();
// Path to the FileStream
string path = objSqlCmd.Parameters["@filepath"].Value.ToString();
// Reset command object to get FileStream
objSqlCmd = new SqlCommand(
"SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()",
objSqlConn,
objSqlTrans);
// Execute command object
Object obj = objSqlCmd.ExecuteScalar();
if (obj != DBNull.Value) {
// Byte array representing the FileStream
byte[] fsBytes = (byte[])obj;
SqlFileStream sqlFS = new SqlFileStream(path, fsBytes, FileAccess.Write);
using (FileStream fs = fi.OpenRead()) {
//byte[] b = new byte[1024];
byte[] b = new byte[4096];
int read;
fs.Seek(0, SeekOrigin.Begin);
while ((read = fs.Read(b, 0, b.Length)) > 0) {
sqlFS.Write(b, 0, read);
}
}
sqlFS.Close();
}
// Commit the transaction
objSqlTrans.Commit();
}
catch (Exception ex) {
objSqlTrans.Rollback();
throw ex;
}
}
}发布于 2010-04-05 17:03:30
你已经有了
using (SqlTransaction objSqlTrans = objSqlConn.BeginTransaction())这将导致当使用块结束时事务被回滚,如果它还没有被执行。
所以我会把catch块完全移除。
至于当回滚失败时会发生什么,我首先要认识到这是一个非常糟糕的情况,并遵循Eric关于类似问题的建议。这里
发布于 2010-04-05 16:35:58
这个片段应该是这样的:
using (SqlConnection objSqlConn = new SqlConnection(connStr)) {
objSqlConn.Open();
using (SqlTransaction objSqlTrans = objSqlConn.BeginTransaction()) {
try {
// code
// more code
// and more code
}
catch (Exception ex) {
// What happens if RollBack() has an exception?
try {
objSqlTrans.Rollback();
} catch (Exception ex2) {
/* can't roll back -- db gone? db will do it for us since we didn't commit. */
}
throw;
}
}
}编辑:想想看,在这个特定的情况下,完全不需要尝试/捕捉,因为使用未提交的事务关闭连接会回滚事务,因此块可以如下所示:
using (SqlConnection objSqlConn = new SqlConnection(connStr)) {
objSqlConn.Open();
using (SqlTransaction objSqlTrans = objSqlConn.BeginTransaction()) {
// code
// more code
// and more code
}
}https://stackoverflow.com/questions/2579515
复制相似问题