C# 管理SQL数据库连接会占用许多事务

C# 管理SQL数据库连接会占用许多事务,c#,sql-server,transactions,enterprise-library,connection-pooling,C#,Sql Server,Transactions,Enterprise Library,Connection Pooling,我们有一个DAL,它需要在一个可以回滚或提交的事务中包装许多数据库插入 处理这个问题的最佳实践是什么 我们目前正在做以下工作: 创建数据库连接和事务 用表示要执行的操作的所有类填充集合。通过构造函数传入连接 在try/catch中,循环遍历所有动作类并调用它们的Publish()方法 成功时提交(关闭连接)或错误时回滚(关闭连接) 这个过程可能需要一些时间,而且我们似乎正在耗尽池数据库连接。是否有更好的方法来管理事务 这是使用SQL 2008、.net 3.5和4.1版本的企业库数据访问。您键入

我们有一个DAL,它需要在一个可以回滚或提交的事务中包装许多数据库插入

处理这个问题的最佳实践是什么

我们目前正在做以下工作:

  • 创建数据库连接和事务
  • 用表示要执行的操作的所有类填充集合。通过构造函数传入连接
  • 在try/catch中,循环遍历所有动作类并调用它们的Publish()方法
  • 成功时提交(关闭连接)或错误时回滚(关闭连接)
  • 这个过程可能需要一些时间,而且我们似乎正在耗尽池数据库连接。是否有更好的方法来管理事务


    这是使用SQL 2008、.net 3.5和4.1版本的企业库数据访问。

    您键入错误,或者问题可能是因为您正在将SqlConnection传递给发布方法(而不是传递SqlTransaction)

    SqlTransaction有一个connection属性,所有更新都应该使用该属性

    所以你想做一些像

    // Create connection
    SqlConnection connection = ObtainSqlConnection()
    
    // Create transaction
    SqlTransaction sqlTransaction = connection.BeginTransaction();
    
    try
    {    
        foreach (Action action in collectionOfActionsToPerform)
        {
            action.Publish(sqlTransaction)
        }
    
        sqlTransaction.Commit();
    }
    catch
    {
        sqlTransaction.Rollback();
    }
    

    如果这是一个误解,请尝试发布一些伪代码。

    看看MySpace网站使用SQL Server技术的实现


    他们使用SQL Server Service Broker跨数百个数据库管理数据库事务。

    一些事务最佳做法包括:

    • 使交易尽可能短
    • 在事务中访问尽可能少的数据
    就企业库而言,DAAB是系统事务感知的,因此我会使用TransactionScope。根据你所说的,比如:

    Database database = DatabaseFactory.CreateDatabase();
    
    using (TransactionScope scope =
        new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        foreach(MyClass myClass in myClasses)
        {
             myClass.Publish(database);
        }
    
        scope.Complete();
    }
    
    此示例没有错误处理,并且假设在需要回滚事务时引发异常

    您的交易似乎涉及大量记录,并且花费了相当长的时间。您在一个事务中更新了多少记录?您的交易持续多长时间?您的所有SQL语句都需要在一个事务中,还是可以将它们拆分为较小的事务


    您是否尝试分析SQL语句以确保它们是有效的。另外,请检查您没有执行过多的锁,也没有出现锁定/阻塞问题。

    当您仅使用一个连接在所有类中执行插入操作时,为什么您会说池连接已用完?事实上,我们看到的错误是:超时已过。从池中获取连接之前经过的超时时间。发生这种情况的原因可能是所有池连接都在使用中,并且已达到最大池大小。