SqlTransaction 同一个事务对象可以给不同的两个command对象吗?

时间:2021-12-07 19:25:38
我的业务是要执行几条sql语句和一个存储过程,两者放在同一事务中,要么同时成功,任一失败全部回滚.


                SqlConnection conn = DBConnSql.SqlConn();
                conn.Open();
                SqlTransaction tran = conn.BeginTransaction();
                try
                {
                    DBConnSql.ExcuteNoQueryNotTran(arySQL, conn, tran);  //此处执行sql语句

                   SqlParameter[] parm = new SqlParameter[2];
                    parm[0] = new SqlParameter("@OrderUniqueID", sMainID);
                    parm[1] = new SqlParameter("@CMOrderNo", poNumber);
                    
                     DBConnSql.execStoredProcedure("InsertFulfillmenttoSFC", parm, conn, tran);  //此处执行存储过程
                    tran.Commit();
                }
                catch (Exception err)
                {
                    tran.Rollback();
                    throw err;
                }


执行提示: This SqlTransaction has completed; it is no longer usable.

12 个解决方案

#1


可以。

至于你遇到的异常,你写了try...catch你就丧失了调试能力。你连vs调试器都不能断到抛出异常的那条语句上了,你怎么来调试 execStoredProcedure 方法呢?你又怎么知道ExcuteNoQueryNotTran 有什么错误呢?

如果这两个东西不是你的,那么给它的作者发消息,然后等着修改。

否则,不要乱写try...catch,让你的vs调试器直接在抛出异常的语句上进入调试状态。

#2


两个方法我是参考别人的,请帮忙指点错误,谢谢.


        public static void ExcuteNoQueryNotTran(ArrayList al, SqlConnection con, SqlTransaction tran)
        {
            if (con.State != ConnectionState.Open)
                con.Open();

            SqlCommand cmd = con.CreateCommand();
            cmd.Transaction = tran;
            if (al.Count == 0)
            {
                throw new Exception("SQL Is Null");
            }
            try
            {
                string sql;
                for (int i = 0; i < al.Count; i++)
                {
                    sql = (String)al[i];
                    if (sql.Trim() != "")
                    {
                        cmd.CommandText = sql;
                        cmd.ExecuteNonQuery();
                    }
                }
            }
            catch (Exception ed)
            {
                throw ed;
            }
            finally
            {
                con.Close();
            }
        }

        public static void execStoredProcedure(string sp_name, SqlParameter[] para, SqlConnection con, SqlTransaction tran)
        {
            try
            {
                if (con.State != ConnectionState.Open)
                    con.Open();

                SqlCommand comm = new SqlCommand();
                comm.Connection = con;
                comm.Transaction = tran;

                comm.CommandText = sp_name;
                comm.CommandType = CommandType.StoredProcedure;

                for (int i = 0; i < para.Length; i++)
                {
                    comm.Parameters.Add(para[i]);
                }

                comm.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
            }
        }

#3


我设断点调试,在执行tran.Commit();时出错.

#4


高手指点指点.

#5


where  is   ”tran.Commit();“。。。

#6


在楼主的那段代码中.

#7


谁能给段不同服务器上的SQL Server数据库的事务?

#8


SQL语句和存储过程能同时当一个事务执行??
存储过程里本身就写了commit了,一旦执行不成功,它就自己rollback,你再写commit和rollback当然是无效的

#9


既然要写事务去执行就要用自己写的连接方法去执行,你调取公用的sqlhelper能行吗?先不去管是不是需要同一个command,你ExcuteNoQueryNotTran方法中都已经把SqlConnection连接关闭了,还能正常去执行事务回滚吗

#10


那这样子,存储过程不能和sql语句做事务吗?但现在业务上有这个需求.
有几组数据需要向本地数据表插入,如果成功则执行本地存储过程,向另一台服务器上的数据表中插入数据,任何一个失败则回滚.

#11


 conn.都关闭了,还玩什么 SqlTransaction 同一个事务对象可以给不同的两个command对象吗?

finally
            {
                con.Close();//把这个删除了
            }

#12


引用 10 楼 szjarvis 的回复:
那这样子,存储过程不能和sql语句做事务吗?但现在业务上有这个需求.
有几组数据需要向本地数据表插入,如果成功则执行本地存储过程,向另一台服务器上的数据表中插入数据,任何一个失败则回滚.

你把向本地表插数据,也放到同一个存储过程里不好吗

#1


可以。

至于你遇到的异常,你写了try...catch你就丧失了调试能力。你连vs调试器都不能断到抛出异常的那条语句上了,你怎么来调试 execStoredProcedure 方法呢?你又怎么知道ExcuteNoQueryNotTran 有什么错误呢?

如果这两个东西不是你的,那么给它的作者发消息,然后等着修改。

否则,不要乱写try...catch,让你的vs调试器直接在抛出异常的语句上进入调试状态。

#2


两个方法我是参考别人的,请帮忙指点错误,谢谢.


        public static void ExcuteNoQueryNotTran(ArrayList al, SqlConnection con, SqlTransaction tran)
        {
            if (con.State != ConnectionState.Open)
                con.Open();

            SqlCommand cmd = con.CreateCommand();
            cmd.Transaction = tran;
            if (al.Count == 0)
            {
                throw new Exception("SQL Is Null");
            }
            try
            {
                string sql;
                for (int i = 0; i < al.Count; i++)
                {
                    sql = (String)al[i];
                    if (sql.Trim() != "")
                    {
                        cmd.CommandText = sql;
                        cmd.ExecuteNonQuery();
                    }
                }
            }
            catch (Exception ed)
            {
                throw ed;
            }
            finally
            {
                con.Close();
            }
        }

        public static void execStoredProcedure(string sp_name, SqlParameter[] para, SqlConnection con, SqlTransaction tran)
        {
            try
            {
                if (con.State != ConnectionState.Open)
                    con.Open();

                SqlCommand comm = new SqlCommand();
                comm.Connection = con;
                comm.Transaction = tran;

                comm.CommandText = sp_name;
                comm.CommandType = CommandType.StoredProcedure;

                for (int i = 0; i < para.Length; i++)
                {
                    comm.Parameters.Add(para[i]);
                }

                comm.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
            }
        }

#3


我设断点调试,在执行tran.Commit();时出错.

#4


高手指点指点.

#5


where  is   ”tran.Commit();“。。。

#6


在楼主的那段代码中.

#7


谁能给段不同服务器上的SQL Server数据库的事务?

#8


SQL语句和存储过程能同时当一个事务执行??
存储过程里本身就写了commit了,一旦执行不成功,它就自己rollback,你再写commit和rollback当然是无效的

#9


既然要写事务去执行就要用自己写的连接方法去执行,你调取公用的sqlhelper能行吗?先不去管是不是需要同一个command,你ExcuteNoQueryNotTran方法中都已经把SqlConnection连接关闭了,还能正常去执行事务回滚吗

#10


那这样子,存储过程不能和sql语句做事务吗?但现在业务上有这个需求.
有几组数据需要向本地数据表插入,如果成功则执行本地存储过程,向另一台服务器上的数据表中插入数据,任何一个失败则回滚.

#11


 conn.都关闭了,还玩什么 SqlTransaction 同一个事务对象可以给不同的两个command对象吗?

finally
            {
                con.Close();//把这个删除了
            }

#12


引用 10 楼 szjarvis 的回复:
那这样子,存储过程不能和sql语句做事务吗?但现在业务上有这个需求.
有几组数据需要向本地数据表插入,如果成功则执行本地存储过程,向另一台服务器上的数据表中插入数据,任何一个失败则回滚.

你把向本地表插数据,也放到同一个存储过程里不好吗