C# 造成';SqlTransaction已完成';错误

C# 造成';SqlTransaction已完成';错误,c#,sql-server,visual-studio,transactions,C#,Sql Server,Visual Studio,Transactions,我正在使用VS.net和SQL Server开发一个小型桌面应用程序。 我正在代码中使用SqlTransaction: SqlTransaction tran = null; SqlCommand cmd = new SqlCommand(); int lstInsSubjId = -1; try { using (SqlConnection con = new SqlConnection(connectionString)) { con.Open();

我正在使用VS.net和SQL Server开发一个小型桌面应用程序。 我正在代码中使用
SqlTransaction

SqlTransaction tran = null;
SqlCommand cmd = new SqlCommand();
int lstInsSubjId = -1;

try
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
        con.Open();

        tran = con.BeginTransaction("Transaction1");//Transaction begin
        tran.Save("Savepoint_1");//Savepoint 1

        string sql1 = @"insSubject";
        cmd = new SqlCommand(sql1, con, tran);

        cmd.Parameters.Add("@lstInsSubjId", SqlDbType.Int).Direction = ParameterDirection.Output;
        cmd.Parameters.Add("@sub_name", SqlDbType.VarChar).Value = txtSubjectName.Text.Trim();

        cmd.CommandType = CommandType.StoredProcedure;
        tran.Save("Savepoint_2");//Savepoint 2

        cmd.ExecuteNonQuery();

        lstInsSubjId = Convert.ToInt32(cmd.Parameters["@lstInsSubjId"].Value);

        for (int i = 0; i < clbClasses.CheckedItems.Count; i++)
        {
            int clsId = Convert.ToInt32(((DataRowView)clbClasses.CheckedItems[i]).Row["c_id"].ToString());
            cmd.CommandText = @"INSERT INTO tblClassSubjectMap_mavis(c_id, sub_id) 
                                VALUES(@c_id, @sub_id)";
            cmd.Parameters.Add("@c_id", SqlDbType.Int).Value = clsId;
            cmd.Parameters.Add("@sub_id", SqlDbType.Int).Value = lstInsSubjId;

            cmd.CommandType = CommandType.Text;
            //tran.Save("Savepoint_3");//Savepoint 3

            cmd.ExecuteNonQuery();
        }

        tran.Commit();//Transaction commit
        MessageBox.Show("Records added", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);

        txtSubjectName.Text = "";
        txtSubjectName.Focus();
        frmSubjectBrows.subList.bindListView();
    }
}
catch (SqlException ex)
{
    if (tran != null)
    {
        tran.Rollback();
        MessageBox.Show(ex.Message.ToString() + "\nTransaction Rolledback", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop);
    }
}
SqlTransaction-tran=null;
SqlCommand cmd=新的SqlCommand();
int lstinssubid=-1;
尝试
{
使用(SqlConnection con=newsqlconnection(connectionString))
{
con.Open();
tran=con.BeginTransaction(“Transaction1”);//事务开始
传输保存(“保存点_1”);//保存点1
字符串sql1=@“insSubject”;
cmd=新的SqlCommand(sql1、con、tran);
Add(“@lstinssubid”,SqlDbType.Int).Direction=ParameterDirection.Output;
cmd.Parameters.Add(“@sub_name”,SqlDbType.VarChar).Value=txtSubjectName.Text.Trim();
cmd.CommandType=CommandType.storedProcess;
传输保存(“保存点_2”);//保存点2
cmd.ExecuteNonQuery();
lstinssubid=Convert.ToInt32(cmd.Parameters[“@lstinssubid”].Value);
对于(int i=0;i
在代码末尾,在for循环中,如果有多个选中项,即如果它多次迭代/循环,那么它将抛出一个错误,并且永远不会提交事务。但是,如果它只循环一次,则不会出现错误,事务也会提交

错误消息是:

System.Data.dll中发生类型为“System.InvalidOperationException”的未处理异常

附加信息:此SqlTransaction已完成;它不再可用

在互联网上寻找答案时,一些解决方案表示,如果交易在提交前突然关闭,则可能会发生此类错误。但我不明白交易是怎么结束的


谁能告诉我出了什么问题吗?提前感谢。

为每个命令使用一个新的sqlcommand实例,请参见

请尝试以下代码:

int lstInsSubjId = -1;

try
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
        con.Open();
        SqlCommand cmd = connection.CreateCommand();
        SqlTransaction tran = con.BeginTransaction("Transaction1");//Transaction begin
        cmd.Connection = cmd;
        cmd.Transaction = tran;

        tran.Save("Savepoint_1");//Savepoint 1

        cmd.CommandText = @"insSubject";
        cmd.Parameters.Add("@lstInsSubjId", SqlDbType.Int).Direction = ParameterDirection.Output;
        cmd.Parameters.Add("@sub_name", SqlDbType.VarChar).Value = txtSubjectName.Text.Trim();

        cmd.CommandType = CommandType.StoredProcedure;
        tran.Save("Savepoint_2");//Savepoint 2

        cmd.ExecuteNonQuery();

        lstInsSubjId = Convert.ToInt32(cmd.Parameters["@lstInsSubjId"].Value);

        for (int i = 0; i < clbClasses.CheckedItems.Count; i++)
        {
            int clsId = Convert.ToInt32(((DataRowView)clbClasses.CheckedItems[i]).Row["c_id"].ToString());
            SqlCommand cmd2 = connection.CreateCommand();
            cmd2.Connection = cmd2;
            cmd2.Transaction = tran;

            cmd2.CommandText = @"INSERT INTO tblClassSubjectMap_mavis(c_id, sub_id) 
                                VALUES(@c_id, @sub_id)";
            cmd2.Parameters.Add("@c_id", SqlDbType.Int).Value = clsId;
            cmd2.Parameters.Add("@sub_id", SqlDbType.Int).Value = lstInsSubjId;

            cmd2.CommandType = CommandType.Text;
            //tran.Save("Savepoint_3");//Savepoint 3

            cmd2.ExecuteNonQuery();
        }

        tran.Commit();//Transaction commit
intlstinssubid=-1;
尝试
{
使用(SqlConnection con=newsqlconnection(connectionString))
{
con.Open();
SqlCommand cmd=connection.CreateCommand();
SqlTransaction tran=con.BeginTransaction(“Transaction1”);//事务开始
cmd.Connection=cmd;
cmd.Transaction=tran;
传输保存(“保存点_1”);//保存点1
cmd.CommandText=@“insSubject”;
Add(“@lstinssubid”,SqlDbType.Int).Direction=ParameterDirection.Output;
cmd.Parameters.Add(“@sub_name”,SqlDbType.VarChar).Value=txtSubjectName.Text.Trim();
cmd.CommandType=CommandType.storedProcess;
传输保存(“保存点_2”);//保存点2
cmd.ExecuteNonQuery();
lstinssubid=Convert.ToInt32(cmd.Parameters[“@lstinssubid”].Value);
对于(int i=0;i
将您的交易放入Using语句中。