0

使用企业库数据访问块在单个事务中处理批处理的一系列 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 只是 Database 对象的包装类

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);
    }
}
4

2 回答 2

1

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

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

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

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

如果您仍然有问题,请在 for each 循环中发布您的代码。

编辑

尝试移动线路:

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

交易范围内。

编辑 2

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

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

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

于 2009-10-11T18:18:12.350 回答
0

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

第二次尝试:

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

于 2009-10-18T04:15:41.063 回答