免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1734 | 回复: 7
打印 上一主题 下一主题

【处理中】Innodb 事务问题如何处理更好? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-02-22 15:30 |只看该作者 |倒序浏览
本帖最后由 chinafenghao 于 2013-02-25 10:46 编辑

库存书只有一本的情况下.

对于用户甲来说,他的动作稍微比乙快一点点,其购买过程所触发的动作大致是这样的:
-------------------------------------------------------------------------------
1. SELECT book_number FROM book WHERE  book_id = 123;
book_number大于零,确认购买行为并更新book_number
2. UPDATE book SET book_number = book_number - 1 WHERE  book_id = 123;
购书成功
-------------------------------------------------------------------------------
而对于用户乙来说,他的动作稍微比甲慢一点点,其购买过程所触发的动作和甲相同:
-------------------------------------------------------------------------------
1. SELECT book_number FROM book WHERE  book_id = 123;
这个时候,甲刚刚进行完第一步的操作,还没来得及做第二步操作,所以book_number一定大于零
2. UPDATE book SET book_number = book_number - 1 WHERE  book_id = 123;
购书成功
-------------------------------------------------------------------------------

库存书只有一本了,用户乙是买不到的.

不加显锁的情况下如何解决.
SELECT book_number FROM book WHERE  book_id = 123 for update;

论坛徽章:
8
CU大牛徽章
日期:2013-09-18 15:20:48CU大牛徽章
日期:2013-09-18 15:20:58CU大牛徽章
日期:2013-09-18 15:21:06CU大牛徽章
日期:2013-09-18 15:21:12CU大牛徽章
日期:2013-09-18 15:21:17天秤座
日期:2013-10-30 14:01:03摩羯座
日期:2013-11-29 18:02:31luobin
日期:2016-06-17 17:46:36
2 [报告]
发表于 2013-02-22 18:05 |只看该作者
什么原因要求不加锁呢?
@todayhero

论坛徽章:
0
3 [报告]
发表于 2013-02-22 18:16 |只看该作者
回复 2# chinafenghao

避免意外发生死锁


   

论坛徽章:
8
CU大牛徽章
日期:2013-09-18 15:20:48CU大牛徽章
日期:2013-09-18 15:20:58CU大牛徽章
日期:2013-09-18 15:21:06CU大牛徽章
日期:2013-09-18 15:21:12CU大牛徽章
日期:2013-09-18 15:21:17天秤座
日期:2013-10-30 14:01:03摩羯座
日期:2013-11-29 18:02:31luobin
日期:2016-06-17 17:46:36
4 [报告]
发表于 2013-02-25 10:44 |只看该作者
@todayhero
避免发生死锁主要是通过操作顺序和事物最小化来处理,这种处理方法不科学

论坛徽章:
0
5 [报告]
发表于 2013-02-25 10:48 |只看该作者
回复 4# chinafenghao

也就是说,我上面提到的情况,需要加for update的。


   

论坛徽章:
8
CU大牛徽章
日期:2013-09-18 15:20:48CU大牛徽章
日期:2013-09-18 15:20:58CU大牛徽章
日期:2013-09-18 15:21:06CU大牛徽章
日期:2013-09-18 15:21:12CU大牛徽章
日期:2013-09-18 15:21:17天秤座
日期:2013-10-30 14:01:03摩羯座
日期:2013-11-29 18:02:31luobin
日期:2016-06-17 17:46:36
6 [报告]
发表于 2013-02-25 10:57 |只看该作者
@todayhero
for update
或者串行化,取消并发

论坛徽章:
9
每日论坛发贴之星
日期:2016-01-04 06:20:00数据库技术版块每日发帖之星
日期:2016-01-04 06:20:00每日论坛发贴之星
日期:2016-01-04 06:20:00数据库技术版块每日发帖之星
日期:2016-01-04 06:20:00IT运维版块每日发帖之星
日期:2016-01-04 06:20:00IT运维版块每日发帖之星
日期:2016-01-04 06:20:00综合交流区版块每日发帖之星
日期:2016-01-04 06:20:00综合交流区版块每日发帖之星
日期:2016-01-04 06:20:00数据库技术版块每周发帖之星
日期:2016-03-07 16:30:25
7 [报告]
发表于 2013-02-25 11:02 |只看该作者
不加锁的方式是使用乐观锁的方法,具体可以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:乐观锁的好处是没有死锁,坏处是当同一时间内并发处理的订单量很大时,在同一本书上的轮询时间会非常久。

论坛徽章:
0
8 [报告]
发表于 2013-02-25 11:17 |只看该作者
回复 7# cenalulu


    非常感谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP