企业库数据访问块事务管理最佳实践

时间:2009-10-08 13:51:43

标签: c# sql-server transactions enterprise-library data-access

在使用企业库数据访问块的单个事务中处理批量系列CRUD操作的最佳做​​法是什么,它不会被提升为分布式事务?

修改完整来源:

public void BatchInsertEvents(IList<EventItem> events)
{
    _dataAccessBase = new DataAccessBase("[dbo].[EventInsert]");
    int count = 0;

    try
    {
        using (var scope = 
                    new TransactionScope(TransactionScopeOption.RequiresNew))
        {
            foreach (var eventItem in events)
            {
                _dataAccessBase.ClearParameters();

                _dataAccessBase.AddInParameter("@time", 
                                            DbType.String, eventItem.Time);
                ...more params

                _dataAccessBase.ExecuteNonQuery();
                count++;
            }

            scope.Complete();
        }
}

我的DataAccessBase只是数据库对象的包装类

public class DataAccessBase
{
    private readonly DbCommand _command;
    private readonly Database _database;

    public DataAccessBase(string storedProcName) : this(null, storedProcName)
    {
    }

    public DataAccessBase(string connectionString, string storedProcName)
    {
        _database = string.IsNullOrEmpty(connectionString) ?
                     DatabaseFactory.CreateDatabase() : 
                     DatabaseFactory.CreateDatabase(connectionString);
        _command = _database.GetStoredProcCommand(storedProcName);
    }

    public void AddInParameter<T>(string parameterName, 
                                            DbType parameterType, T value)
    {
        _database.AddInParameter(_command, 
                                parameterName, parameterType, value);
    }


    public void AddOutParameter<T>(string parameterName, 
                                DbType parameterType, int parameterLength)
    {
        _database.AddOutParameter(_command, 
                                parameterName, parameterType, parameterLength);
    }

    public void ClearParameters()
    {
        _command.Parameters.Clear();
    }

    public void ExecuteNonQuery()
    {
        _database.ExecuteNonQuery(_command);
    }
}

2 个答案:

答案 0 :(得分:1)

我猜测正在发生的事情是,你正在使用带有连接池的EntLib。

然后,您将获得一个分布在多个连接上的事务。然后将其升级为分布式事务。

Entlib非常擅长的一件事就是关闭连接。您需要以重用单个连接的方式编写代码。

此链接中解释了其中一些内容:http://msdn.microsoft.com/en-us/library/cc511672.aspx

如果您仍有问题,请在每个循环中发布您的代码。

修改

尝试移动线:

_dataAccessBase = new DataAccessBase("[dbo].[EventInsert]");

在交易范围内。

编辑2

您是否还可以在事务范围内移动_dataAccessBase的声明

DataAccessBase _dataAccessBase = new DataAccessBase("[dbo].[EventInsert]");

这只是为了确保在事务范围之外不使用连接。

答案 1 :(得分:0)

编辑:发布后我意识到我几乎完全复制了Shiraz Bhaiji已经提出的建议。请忽略。

第二次尝试:

请提供DatabaseFactory.CreateDatabase()的代码。你有偶然的额外TransactionScope吗?如果是这样,并且您使用相同的TransactionScopeOption.RequiresNew,您可以轻松升级到DTC。