因为现在在外面突然间想到的问题,请大家分析一下
如我有两个表
一个是VIP卡表如有
VIPNO Amount
001 1000 一个是Invoice发票表(也就是消费记录)
ID VIPNO Amount Date 我原先的代码为C#
建立链接 oo
启动事务
try
{
Decimal payAmount = 1000;
VIPNOInfo info = new VIPNOInfo(oo,"001") 取出001记录的对像
if(info.Amount < payAmount)
{
throw new Exception("VIP金额不够");
}
info.Amount = info.Amount - payAmount;
VIP.Update(oo,info); 更新VIP减去收费
//添加发票记录
InvoiceInfo infoInvoice = new InvoiceInfo();
infoInvoice.VIPNO = info.VIPNO;
infoInvoice.Amount = payAmount;
infoInvoice.Date = DateTime.Now;
Invoice.Insert(oo,infoInvoice);
}
catch(Exception ex)
{
回滚事务
Tools.Alert(ex.Message);//报错提示
}
finaly
{
结束事务
结束链接
清空资源
}
开始我以为上面的代码是不会有错的,但现在在客户这里就出错了VIP卡收费超额的问题
我想应该是一个VIP卡在同一时间进行收费的问题
如两个收费地方,同时对一个VIP卡001进行收费
1点击收费时,
if(info.Amount < payAmount)
通过,但事务还没有提交的时候
2点击收费
if(info.Amount < payAmount)
也通过的时候
就会造成收费超额的问题 然后我想给VIP添加Updlock但好像也是不行,
因为好像也会和上面的问题一样
最后想添加tablock但这样的话效率太差了 大家有什么好的操作流程 --------------------------------------------------------------
在上一贴中
http://topic.csdn.net/u/20090102/15/eb0843a3-0ec7-42bf-96c6-46e42bda9a74.html
大家都说用ROWLOCK
但我回来测试了一下还是不行的
因为如在这里的1点击收费时,
if(info.Amount < payAmount)
通过,但事务还没有提交的时候
2点击收费
就算我上面添加了ROWLOCK但是在2这里还是可以得到他的记录
那么同样这里的判断也会通过
而我要的是,当VIP001在1的地方读取的时候,其他的地方都不可以读取这条记录
直到1操作提交或回滚为止
因为如果1没有提交,而2读到的时候就会1还没有扣钱,而2又去判断钱是否足够
就会造成超额消费的问题,(PS这里要求用程序处理,不要像触发器判断的什么)
if(info.Amount < payAmount)
也通过的时候
就会造成收费超额的问题
谢谢
如我有两个表
一个是VIP卡表如有
VIPNO Amount
001 1000 一个是Invoice发票表(也就是消费记录)
ID VIPNO Amount Date 我原先的代码为C#
建立链接 oo
启动事务
try
{
Decimal payAmount = 1000;
VIPNOInfo info = new VIPNOInfo(oo,"001") 取出001记录的对像
if(info.Amount < payAmount)
{
throw new Exception("VIP金额不够");
}
info.Amount = info.Amount - payAmount;
VIP.Update(oo,info); 更新VIP减去收费
//添加发票记录
InvoiceInfo infoInvoice = new InvoiceInfo();
infoInvoice.VIPNO = info.VIPNO;
infoInvoice.Amount = payAmount;
infoInvoice.Date = DateTime.Now;
Invoice.Insert(oo,infoInvoice);
}
catch(Exception ex)
{
回滚事务
Tools.Alert(ex.Message);//报错提示
}
finaly
{
结束事务
结束链接
清空资源
}
开始我以为上面的代码是不会有错的,但现在在客户这里就出错了VIP卡收费超额的问题
我想应该是一个VIP卡在同一时间进行收费的问题
如两个收费地方,同时对一个VIP卡001进行收费
1点击收费时,
if(info.Amount < payAmount)
通过,但事务还没有提交的时候
2点击收费
if(info.Amount < payAmount)
也通过的时候
就会造成收费超额的问题 然后我想给VIP添加Updlock但好像也是不行,
因为好像也会和上面的问题一样
最后想添加tablock但这样的话效率太差了 大家有什么好的操作流程 --------------------------------------------------------------
在上一贴中
http://topic.csdn.net/u/20090102/15/eb0843a3-0ec7-42bf-96c6-46e42bda9a74.html
大家都说用ROWLOCK
但我回来测试了一下还是不行的
因为如在这里的1点击收费时,
if(info.Amount < payAmount)
通过,但事务还没有提交的时候
2点击收费
就算我上面添加了ROWLOCK但是在2这里还是可以得到他的记录
那么同样这里的判断也会通过
而我要的是,当VIP001在1的地方读取的时候,其他的地方都不可以读取这条记录
直到1操作提交或回滚为止
因为如果1没有提交,而2读到的时候就会1还没有扣钱,而2又去判断钱是否足够
就会造成超额消费的问题,(PS这里要求用程序处理,不要像触发器判断的什么)
if(info.Amount < payAmount)
也通过的时候
就会造成收费超额的问题
谢谢
的意思就是
VIPNOInfo info = new VIPNOInfo(oo,"001") 取出001记录的对像
原来的语句为
Select * From VIP Where VIPNO='001'
变为
Select * From VIP WITH(ROWLOCK) Where VIPNO='001'谢谢
注意: 锁定数据库的一个表的区别SELECT * FROM table WITH (HOLDLOCK)
其他事务可以读取表,但不能更新删除SELECT * FROM table WITH (TABLOCKX)
其他事务不能读取表,更新和删除
让该用户操作完毕后,把标记改为N,这样其他用户才能操作这条记录.不过这种做法,一旦遇到该用户长时间操作这条记录时,或操作过程中遇到以外,这条记录的标记不能恢复为N,需要人工干预强制恢复为N,否则其他用户就不能操作这条记录了.
------------------------------------------------
我用这条语句,我的其他事务都可以读到这条信息啊所以我才会再开贴 来问的谢谢
SELECT * FROM tablename WITH (paglock,xlock) WHERE id=3
------------------------------------------------
这样是可以,
但是这样好像你tablock一样
我的其他记录也查询不出来了所以这不个不能,我要的是只锁死这一条的谢谢