- 论坛徽章:
- 9
|
不加锁的方式是使用乐观锁的方法,具体可以wiki。对于这个例子的解决方案应该是:
book_number表,添加一列锁指定列,lastsuccess_orderid用于标明上一次成功购买的订单号
库存书只有一本的情况下.
对于用户甲来说,他的动作稍微比乙快一点点,其购买过程所触发的动作大致是这样的:
甲的订单号是10001
-------------------------------------------------------------------------------
1. SELECT book_number,lastsuccess_orderid FROM book WHERE book_id = 123;
book_number大于零,确认购买行为并更新book_number.
并且得知上一个成功订单号是 10000
2. UPDATE book SET book_number = book_number - 1, lastsuccess_orderid = 10001 WHERE book_id = 123 and lastsuccess_orderid = 10000;
判断影响行数,如果成功更新,则说明该次乐观锁获取成功。后面执行订单逻辑
-------------------------------------------------------------------------------
而对于用户乙来说,他的动作稍微比甲慢一点点,其购买过程所触发的动作和甲相同:
乙的订单号是10002
-------------------------------------------------------------------------------
1. SELECT book_number,lastsuccess_orderid FROM book WHERE book_id = 123;
这个时候,甲刚刚进行完第一步的操作,还没来得及做第二步操作,所以book_number一定大于零。
且订单号也同样是10000
2. UPDATE book SET book_number = book_number - 1,lastsuccess_orderid = 10002 WHERE book_id = 123 and lastsuccess_orderid = 10000;
更新影响行数=0,表示在step1&2之间已经有其他订单成功。
于是再重新从step1开始循环。直到乐观锁得到为止。
-------------------------------------------------------------------------------
PS:乐观锁的好处是没有死锁,坏处是当同一时间内并发处理的订单量很大时,在同一本书上的轮询时间会非常久。 |
|