C# 嵌套事务插入失败

C# 嵌套事务插入失败,c#,sql-server,transactions,ado.net,dapper,C#,Sql Server,Transactions,Ado.net,Dapper,我使用c#上的IDBConecction接口来使用嵌套事务。我必须找到将数据插入两个不同表的方法,但是当涉及到第二个插入时,第一个插入事务会锁定第二个,导致超时异常 public void FirstInsert() { using (var cn = new Connection().GetConnection()) { cn.Open(); using (var tran = cn.BeginTransaction()) {

我使用c#上的IDBConecction接口来使用嵌套事务。我必须找到将数据插入两个不同表的方法,但是当涉及到第二个插入时,第一个插入事务会锁定第二个,导致超时异常

public void FirstInsert()
{
    using (var cn = new Connection().GetConnection())
    {
        cn.Open();
        using (var tran = cn.BeginTransaction())
        {
            try
            {
                //1st insert
                SecondInsert() //calling second insert method
                tran.Commit();                
            }
            catch
            {
                tran.Rollback();
            }
        }
    }
}

public void SecondInsert()
{
    using (var cn = new Connection().GetConnection())
    {
        cn.Open();
        using (var tran = cn.BeginTransaction())
        {
            try
            {
                //2nd insert, this one fails
                tran.Commit();                
            }
            catch
            {
                tran.Rollback();
            }
        }
    }
}
当我在SqlServer上检查First insert是否具有SPID 56时,当使用SPID 57执行第二次插入时,我使用

exec sp_who2
在SPID 57的“BlkBy”一栏中,它表示它被SPID 56阻止


我怎样才能克服这些问题

两种操作都使用一个连接。这可能涉及传递连接对象


通常,每个请求的连接+事务模式很好地解决了这个问题。用各种方法打开连接是一种代码味道。这表明基础结构无法处理该问题。

您的操作是正确的,但第二个方法中不需要单独的连接对象和事务对象,因为对
secondinsert()
的调用已经在事务范围内。您的代码可以简单地

public void FirstInsert(){
    using (var cn = new Connection().GetConnection()){
        cn.Open();
        using (var tran = cn.BeginTransaction()){
            try{
                //1st insert
                SecondInsert() //calling second insert method
                tran.Commit();                
            }
            catch{
                tran.Rollback();
            }
        }
    }
}

public void SecondInsert(){

               //perform second insert operation             
        }
    }
}

您能显示连接字符串和插入项吗?对两个不同表的插入不应该互相阻塞,通常来自同一客户机的两个相同连接将共享一个分布式事务,但这可以在连接字符串中禁用。根据示例代码打开两个连接是没有意义的,但我希望您有理由这样做。使用MARS连接字符串选项(多个活动结果集)可以让您并行地从两个查询中检索结果,但从您的描述中,您不需要这样做。@请稍加更正:两个SqlConnection对象从不共享同一事务。即使它是分布式的,它仍然显示为与SQL Server的两个会话。我需要在每个方法中都有一个事务和连接,因为除了示例中的方法之外,我还需要从其他方法调用第二个方法。基本上,我需要每个可提交的事务都在一个单独的方法中,以避免重复,也可以是这些方法被调用到任何地方。@ JeCAROF,在这种情况下,考虑将同一个连接/Trand对象传递给您的第二个方法,并使用它。但是如果我从第二个方法调用.Actuple(),整个交易都被提交了吗?这是因为在第二次插入之后,我可能需要调用另一个插入,正如我前面提到的,我需要几乎每个插入/更新都在一个单独的方法中,以防我只需要从另一个地方调用它,例如只调用第二次插入。我想要类似于在WCF中使用[Autocomplete(true)]属性,但不使用WCF,WCF通过使用适当的绑定来跟踪所有事务,直到服务调用结束为止,不会出现错误异常。