我在交易中有以下代码。我不确定应该在何时/何时提交我的工作单位。
故意,我没有提到我正在使用什么类型的Respoistory - 例如。 Linq-To-Sql,实体框架4,NHibernate等
如果有人知道在哪里,他们可以解释他们为什么说,在哪里? (我试图通过示例来理解模式,而不是让我的代码工作)。
这就是我所拥有的: -
using
(
TransactionScope transactionScope =
new TransactionScope
(
TransactionScopeOption.RequiresNew,
new TransactionOptions
{ IsolationLevel = IsolationLevel.ReadUncommitted }
)
)
{
_logEntryRepository.InsertOrUpdate(logEntry);
//_unitOfWork.Commit(); // Here, commit #1 ?
// Now, if this log entry was a NewConnection or an LostConnection,
// then we need to make sure we update the ConnectedClients.
if (logEntry.EventType == EventType.NewConnection)
{
_connectedClientRepository.Insert(
new ConnectedClient { LogEntryId = logEntry.LogEntryId });
//_unitOfWork.Commit(); // Here, commit #2 ?
}
// A (PB) BanKick does _NOT_ register a lost connection,
// so we need to make sure we handle those scenario's as a LostConnection.
if (logEntry.EventType == EventType.LostConnection ||
logEntry.EventType == EventType.BanKick)
{
_connectedClientRepository.Delete(
logEntry.ClientName, logEntry.ClientIpAndPort);
//_unitOfWork.Commit(); // Here, commit #3 ?
}
_unitOfWork.Commit(); // Here, commit #4 ?
transactionScope.Complete();
}
答案 0 :(得分:3)
回答这个问题的一个好起点是企业架构模式中的工作单元定义(http://martinfowler.com/eaaCatalog/unitOfWork.html):
维护受业务事务影响的对象列表,并协调写入更改和解决并发问题。
您的工作单元的边界由业务事务的边界定义 - 在这种情况下,它与数据库事务的边界同义(但是在长时间运行的业务事务的情况下,跨越多个请求可能不是这样的。)
从上面的定义向后工作,根据我对所显示的代码片段的理解,你应该在业务交易结束时提交工作单元(#4)。
另外,您的数据库事务范围应始终小于UoW的范围(即tx范围位于对UoW.Begin()和UoW.Commit()的调用之间。如果您的UoW跨越多个数据库事务,那么如果其中一个内部事务失败,您将使用补偿事务来“重新平衡”UoW。在这种情况下,特别是如果您的UoW在UoW.Begin()和UoW.Commit()中创建它自己的数据库事务边界,我会删除事务范围,因为这只是在代码中添加了不必要的噪声。
答案 1 :(得分:0)
在对所有存储库进行所有操作后,在#4处提交。如果您事先提交,则不会提交在该调用之后所做的更改。
答案 2 :(得分:0)
假设您的数据存储正在分配ID,您必须提交#1(使用NHibernate,您甚至应该刷新),然后在#4结束。