当分配给命令的连接处于挂起的本地trans时,ExecuteReader需要命令才能具有事务

我必须在单个事务中插入两个表,下面要执行的查询。 其次在SqlDataReader上获取exceptionread = comm.ExecuteReader();

public void SqlExecuteNonQuery(Customer obj) { //string query = "DECLARE @_customerID int "; string query1 = "INSERT INTO customer (customerName,customerSex,Email) VALUES ('" + obj.name + "','" + obj.sex + "','" + obj.Email + "') "; //string query2 = "SET @_customerID =@@identity "; string query3 = "INSERT INTO customerDetails(customerID,customerAddress,customerPhone) VALUES (" + obj.id + ",'" + obj.address + "','" + obj.phone + "') "; string CS = ConnectionName; using (SqlConnection conn = new SqlConnection(CS)) { conn.Open(); using (SqlCommand command = new SqlCommand("SELECT Email FROM Customer where Email ='" + obj.Email + "'", conn)) { SqlDataReader reader = command.ExecuteReader(); try { if (reader.Read()) { throw new Exception("User already exist for the email"); } else { reader.Close(); using (SqlCommand cmd = GetCommand(query1, conn)) { SqlTransaction transaction; transaction = conn.BeginTransaction(); try { cmd.Transaction = transaction; cmd.ExecuteNonQuery(); using (SqlCommand comm = new SqlCommand("Select customerID from Customer where email = '" + obj.Email + "'", conn)) { SqlDataReader read = comm.ExecuteReader(); try { while (read.Read()) { obj.id = (int)read[0]; } using (SqlCommand cmd1 = GetCommand(query3, conn)) { try { cmd1.ExecuteNonQuery(); } catch (Exception ex1) { Console.WriteLine("Comit Exception Type: {0}", ex1.GetType()); Console.WriteLine("error in inserting - {0}", ex1.Message); try { transaction.Rollback(); } catch (Exception ex2) { Console.WriteLine("RollBack Exception Type: {0}", ex2.GetType()); Console.WriteLine("Message: {0}", ex2.Message); } } } transaction.Commit(); Console.WriteLine("Successfull transaction"); } catch (Exception ex) { Console.WriteLine("Error type:", ex.GetType()); Console.WriteLine("Message:", ex.Message); } finally { read.Close(); } } } catch (Exception ex) { Console.WriteLine("Comit Exception Type: {0}", ex.GetType()); Console.WriteLine("error in inserting - {0}", ex.Message); try { transaction.Rollback(); } catch (Exception ex2) { Console.WriteLine("RollBack Exception Type: {0}", ex2.GetType()); Console.WriteLine("Message: {0}", ex2.Message); } } finally { transaction.Dispose(); } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } } } 

问题是你在与cmd相同的连接上执行cmd1,因此在该连接上有一个打开的事务,但你没有设置cmd1.Transaction …所以解决方案是

 cmd1.Transaction = transaction; 

之前

 cmd1.ExecuteNonQuery(); 

您可能需要考虑切换到使用TransactionScope ,然后将其隐式用于其中的所有命令。 你会用它像:

 using(var scope = new TransactionScope()) { using(var conn = new SqlConnection(/*...*/)) { //As many nested commands, etc, using the above connection. //but don't need to create a SqlTransaction object nor //in any way reference the scope variable } scope.Complete(); }