今天因为并发的问题,又讨论了一遍。之前以为同时两个线程开启,线程A加了更新锁,线程B没有加,线程A更新后,线程B也会继续下去代码。但是今天测试了一下,原来线程A更新后(解锁),线程B将不会继续,会出现数据库语句出现修改之类的提示。
写法 SELECT * FROM TABLE WITH UPDLOCK WHERE ID=1
A代码段示例:
using (TransactionScope trans = new TransactionScope())
{
using (var dbContext = new Qxun.Activity.DAL.ActivityDbContext())
{
string sqlStr = string.Format("SELECT * FROM TABLE WITH(UPDLOCK) WHERE ID={0} ", crossDomainPayRecord.ID);
VIPWeRegister046Play model = dbContext.Database.SqlQuery(sqlStr).FirstOrDefault();
if (Status == 0)//说明出现问题
{
model.Status = Status;
dbContext.Update
trans.Complete();
return Content(res.ToXml());
}
trans.Complete();
}
}
B代码段示例 :
using (ActivityDbContext dbContext=new ActivityDbContext())
{
List
foreach (var item in model)
{
item.Status= 2;
dbContext.Insert
dbContext.Update
}
List share = dbContext.Shares.ToList();
if (share.Count == 0)
{
dbContext.Insert(new Share());
}
share = dbContext.Shares.ToList();
foreach (var item in share)
{
item.MerchantWeixinUserID = 1;
dbContext.Update(item);
}
}
1.线程A进入更新锁代码段,线程B将会停止在dbContext.Update处,不会再继续下去(解锁操作两种:1.更新操作(非事务处理);2.事务处理结束(处于事务))
接下来有三种情况:
1.1线程A不进行更新操作(没有update操作,即使没有改变值),线程A结束事务后(解锁),线程B将继续运行
1.2线程A进行了更新操作,即此时Status状态值更改为0,线程B将会跳转入异常,异常详细上会有数据库信息更改之类的提示
1.3线程A一直停留在断点,不进行解锁操作,时间一旦达到限制,则线程B将会提示请求超时之类的(由于数据库请求是有设定时限的)
2.线程A未进入更新锁代码段,则线程B按照正常运行
3.线程A进入更新锁代码段时,线程B也可以使用select获取,即List
4.一旦A线程进入更新锁代码,且进行了update操作,线程B中的插入更新dbContext.Insert
5.一旦A线程进入更新锁代码,且未进行update操作,线程B中的插入dbContext.Insert
异常提示:存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除。刷新 ObjectStateManager 项。