这个问题有三个部分:
代码可以从这里下载
假设DataLayer(DAL)由WCF服务实现,并且客户端代码由Main对其操作的调用组成:
public void Main(string[] args)
{
var dal = new DataLayerServiceClient();
var accounts = dal.GetAccounts();
int accountId = accounts.First().AccountId;
for (int i = 0; i < 10000; i++)
{
using (TransactionScope scope = new TransactionScope())
{
var account = dal.GetAccountById(accountId);
account.Balance++;
dal.Update(account);
scope.Complete();
}
}
}
还假设:
同时运行两个客户端进程。
预期结果是,两个客户端退出后的账户余额应该比两个客户端启动前大20000。
两个客户端退出后的帐户余额是10000到20000之间的值。在某些情况下,其中一个客户端因以下错误而中止:
事务(进程ID)在锁资源上与另一个进程死锁,并被选为死锁受害者
每个客户端上的TransactionScope范围内包含的操作并不与其他客户端的操作作为一个整体串联运行。来自两个事务的读取和写入混合在一起,并且丢失了一些增量。
int i = 0;
while(i < 10000)
{
try
{
using (TransactionScope scope = new TransactionScope())
{
var account = dal.GetAccountById(accountId);
account.Balance++;
dal.Update(account);
scope.Complete();
}
i++;
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message} : restarting");
}
}
当然,这是非常低效的,但它按预期工作,并演示了事务如何隔离资源管理器上的操作。