/******** 局域网中的所有SQL服务器 EXEC MASTER..XP_CMDSHELL 'OSQL -L' /********** 加锁 *************** 设table1(A,B,C) A B C a1 b1 c1 a2 b2 c2 a3 b3 c31)排它锁 新建两个连接 在第一个连接中执行以下语句 begin tran update table1 set A='aa' where B='b2' waitfor delay '00:00:30' --等待30秒 commit tran 在第二个连接中执行以下语句 begin tran select * from table1 where B='b2' commit tran若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒2)共享锁 在第一个连接中执行以下语句 begin tran select * from table1 holdlock -holdlock人为加锁 where B='b2' waitfor delay '00:00:30' --等待30秒 commit tran在第二个连接中执行以下语句 begin tran select A,C from table1 where B='b2' update table1 set A='aa' where B='b2' commit tran若同时执行上述两个语句,则第二个连接中的select查询可以执行 而update必须等待第一个连接中的共享锁结束后才能执行 即要等待30秒3)死锁 增设table2(D,E) D E d1 e1 d2 e2 在第一个连接中执行以下语句 begin tran update table1 set A='aa' where B='b2' waitfor delay '00:00:30' update table2 set D='d5' where E='e1' commit tran
在第二个连接中执行以下语句 begin tran update table2 set D='d5' where E='e1' waitfor delay '00:00:10' update table1 set A='aa' where B='b2' commit tran同时执行,系统会检测出死锁,并中止进程 -------------------------------------------------------------- SET IMPLICIT_TRANSACTIONS ON --用户每次必须显式提交或回滚。否则当用户断开连接时, --事务及其所包含的所有数据更改将回滚SET IMPLICIT_TRANSACTIONS OFF --自动提交模式。在自动提交模式下,如果各个语句成功 --完成则提交。
EXEC MASTER..XP_CMDSHELL 'OSQL -L' /********** 加锁 ***************
设table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c31)排它锁
新建两个连接
在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B='b2'
commit tran若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒2)共享锁
在第一个连接中执行以下语句
begin tran
select * from table1 holdlock -holdlock人为加锁
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran在第二个连接中执行以下语句
begin tran
select A,C from table1
where B='b2'
update table1
set A='aa'
where B='b2'
commit tran若同时执行上述两个语句,则第二个连接中的select查询可以执行
而update必须等待第一个连接中的共享锁结束后才能执行 即要等待30秒3)死锁
增设table2(D,E)
D E
d1 e1
d2 e2
在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30'
update table2
set D='d5'
where E='e1'
commit tran
在第二个连接中执行以下语句
begin tran
update table2
set D='d5'
where E='e1'
waitfor delay '00:00:10'
update table1
set A='aa'
where B='b2'
commit tran同时执行,系统会检测出死锁,并中止进程
--------------------------------------------------------------
SET IMPLICIT_TRANSACTIONS ON --用户每次必须显式提交或回滚。否则当用户断开连接时,
--事务及其所包含的所有数据更改将回滚SET IMPLICIT_TRANSACTIONS OFF --自动提交模式。在自动提交模式下,如果各个语句成功
--完成则提交。
客户端只是发请求(可能只是一个Socket请求)
然后中间层根据业务建立相应队列进行执行
可以在中间层设定队列长度以及超时
这样客户端就不会等很长时间
我定义有一批紧俏商品,每类商品规定了限量,对应表如下 T_LimitWare (WareCode,LimitNum)
数据如: 001 20
002 100
……
当抢购商品的时候,系统首先从次表中按商品编码(WareCode)来检测仓库中还存在的数量(LimitNum),当购买量小于对应商品的 LimitNum时候,交易成功(此时应该更改LimitNum的值),否则失败。当此类紧俏商品销售完后,则对应商品记录从此表中删除! 因为业务实际情况,抢购总是发生在每一天的特定时候,而且客户抢购商品的先后顺序也类似(比如首先看001还有没有库存,如果没有则查看002……),也就是说对此表中同一条记录的并发访问情况在抢购时候非常普遍,而且因为终端很多(50个以上),造成此时候系统的访问速度非常的慢 对以上描述的问题,如果单单靠数据库的锁来解决并发以保证数据上的正确,而因为锁而又导致系统此时的串行运行……系统运行速度让操作员也让客户无法接受,请教有没有好的是方法或者设计,来解决此问题……
1. 立即出库。
2. 出库不等于销售。
3. 销售不成立则抢购品返库。具体地说,就是:设置“待销售库”用来保存“哪一台POS抢占了某些商品”的资料。POS开始交易时,将抢购品出库到“待销售库”中,交易成交时真正记录销售并移出货品,交易作废(或者超时被强制作废)时将货品返回仓库。这个设计,中间环节不需要加锁,可以有更高的系统吞吐量,就是我说的“利用业务原则将这些事务在逻辑上联系起来”而不需要真正做一个“硬性的”事务。
to :w_rose(w_rose)
……交易成交时真正记录销售并移出货品,交易作废(或者超时被强制作废)时将货品返回仓库
执行此真正的交易操作时候还不照样需要经过数据(库存)的校验以及记录的更新吗?好象还是没有解决问题八…… 或许没理解 w_rose(w_rose)的意思
当取出每个POS申请抢购数量的时候不做数量的判断,即为出库而非销售。而后中间层程序控制每隔一段时间,提交一次对抢购商品表的检索与更新。比如在一个时间段内,有5个POS提交了对对应商品的抢购需求,我对5个POS终端的同一商品的数量进行累加,而后一次性的到数据表中进行数量的判断,如果请求量小于剩余库存则交易成功(一起提交5个POS端的请求),如过总数量超过了总的库存,则回滚这5个所有的请求,当然复杂点的比如可以按从请求数量的从大到小来单个取消这5个中的某一个或多个请求(按实际的抢购申请量和库存量)……
这样可以大大的减低对同一数据表同一行数据的并发请求而导致队列的串行时间消耗……
当然这样做起来肯定会比较麻烦,特别是时间间隔的控制和对多个用户进行一个事物的封装 ,但我想应该可以实现
大家讨论一下,可行不可行!?
update tablename 锁
set col1=数值
where 条件增加删除情况一样
大多数的"用户"不是login!(多个连接使用同一个 login)
如果你的应用确实不允许多个连接客户端同时修改
我有一个利用"全局临时表"特性的解决方案:
太晚了!
明天继续...
瘫了比帐错了好吧