在使用企业库数据访问块的单个事务中处理批量系列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);
}
}
答案 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。