C# 嵌套事务插入失败
我使用c#上的IDBConecction接口来使用嵌套事务。我必须找到将数据插入两个不同表的方法,但是当涉及到第二个插入时,第一个插入事务会锁定第二个,导致超时异常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()) {
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通过使用适当的绑定来跟踪所有事务,直到服务调用结束为止,不会出现错误异常。