• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#lock避免多人同时操作

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

当多人同时操作时有可能会出现一些意外情况,我们可以应用lock关键词,lock是将语句块标示为临界区,确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其它线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

以下以订单号做一个实验。

Table表結構如下:

Table表結構
ifobject_id('tb') isnotnulldroptable tb
createtable tb(PONo nvarchar(10) ,CreateBy nvarchar(20) ,CreateDate smalldatetime)
go
select*from tb
go
--PONo CreateBy CreateDate
--
---------- -------------------- -----------------------
--
(0 个数据列受到影响)

前台代码如下:

前臺代碼如下
protectedvoid Button1_Click(object sender, EventArgs e)
{
string name = User.Identity.Name.ToString();
string PONo = TestFactory.GetPONumber(name);
Response.Write(PONo);
}

后臺代碼如下,未使用lock:

后臺代碼,未使用lock:
publicclass TestFactory
{
privatestaticobject objPONo =newobject();

publicstaticstring GetPONumber(string name)
{
//lock (objPONo)
//{
//定義訂單號PONo
string PONo =string.Empty;

//將訂單號PONo自動加1
string strsql ="update tb set PONo=PONo+1,CreateBy='"+ name +"',CreateDate=getdate()";
int i = SQLHelper.ExecuteNonQuery(strsql);

//如果登陸人為Takako,線程睡眠3秒.以作測試
if (name.ToLower() =="takako_yang")
{
Thread.Sleep(
3000);
}

//如果update失敗,表示DB中不存在資料,則往DB塞入第一筆訂單號PONo:1000000000.
if (i ==0)
{
strsql
="insert into tb values(1000000000,'"+ name +"',getdate())";
i
= SQLHelper.ExecuteNonQuery(strsql);
}

//選出最后一筆
strsql ="select max(PONo) from tb";
object o = SQLHelper.ExecuteScalar(strsql);
if (o == DBNull.Value)
{
PONo
="1000000000";
}
else
{
PONo
= SQLHelper.ExecuteScalar(strsql).ToString();
}
return PONo;
//}
}
}

实验者路人甲、路人乙,在程序中添加了一段Thread.Sleep(3000),判断当实验者为甲时,睡眠3秒再继续后面的动作。

当甲按下甲页面上的按钮,乙在1秒后也按下乙页面上按钮;

这时乙页面会往DB塞一笔订单号PONo:1000000000;

3秒后,甲页面也会往系统塞一笔订单号PONo:1000000000;

很显然,出现了两笔一模一样的订单号,这不是我们想要的。

 

后台代码,使用lock后

后臺代碼,使用lock后:
publicclass TestFactory
{
privatestaticobject objPONo =newobject();

publicstaticstring GetPONumber(string name)
{
lock (objPONo)
{
//定義訂單號PONo
string PONo =string.Empty;

//將訂單號PONo自動加1
string strsql ="update tb set PONo=PONo+1,CreateBy='"+ name +"',CreateDate=getdate()";
int i = SQLHelper.ExecuteNonQuery(strsql);

//如果登陸人為Takako,線程睡眠3秒.以作測試
if (name.ToLower() =="takako_yang")
{
Thread.Sleep(
3000);
}

//如果update失敗,表示DB中不存在資料,則往DB塞入第一筆訂單號PONo:1000000000.
if (i ==0)
{
strsql
="insert into tb values(1000000000,'"+ name +"',getdate())";
i
= SQLHelper.ExecuteNonQuery(strsql);
}

//選出最后一筆
strsql ="select max(PONo) from tb";
object o = SQLHelper.ExecuteScalar(strsql);
if (o == DBNull.Value)
{
PONo
="1000000000";
}
else
{
PONo
= SQLHelper.ExecuteScalar(strsql).ToString();
}
return PONo;
}
}
}

將DB中的資料刪光,delete tb

和上一個實驗一樣,甲按下甲頁面按鈕后,乙在1秒后也按下乙頁面按鈕.

結果如下:甲頁面在3秒后顯示了订单号PONo:1000000000;乙在3秒后顯示了訂單號PONo:1000000001。

這正是理想的結果。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
偶对学习C#以及理解.Net平台的一些看法(一,Prerequisites)发布时间:2022-07-10
下一篇:
c#日期时间截取发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap