作者roga (任性)
看板PHP
标题Re: [请益] 同时写入资料库的问题
时间Fri Mar 25 12:33:01 2011
※ 引述《sunz5010 (FoFo)》之铭言:
: : 以上是先拿出库存再来算数量,但是您要考虑 innodb_lock_wait_timeout ,
: : 这个预设是 50 秒,等起来有点久。或是考虑另一种作法,不要 select 直接计算
: : $sth = $dbh->prepare("UPDATE scart SET qty = qty - :qty
: : WHERE id = :id and qty - :qty > 0");
: : $sth->execute(array(':qty'=>$qty, ':id'=>$id));
补充一下,如果是一次购买多件商品,这边可以
$dbh->beginTransaction();
每执一行 update 叙述之後,拿 rowCount() 来看
$sth = $dbh->prepare("UPDATE scart SET qty = qty - :qty
WHERE id = :id and qty - :qty >= 0");
$sth->rowCount();
foreach($productIdList as $pid)
{
$sth->execute(array(':qty' => $qty, ':id' => $pid));
if($sth->rowCount() == 0)
{
// 简化一点,在途中有遇到 rowCount 回传是 0 就直接 rollback
throw new Exception('update error.');
}
}
$dbh->commit();
然後 PDO 自己 commit failed 也会 throw exception
所以只要在外层 catch exception 然後 $dbh->rollback() 即可。
流程控制大概是这样。
: : 然後 update 失败就代表库存不够,叫使用者重新回页面购买。
: 谢谢你的分享、我也顺便分享一下我的作法
: 我原本的问题是
: 「仓库」:1颗苹果
: 「甲」=>想买苹果
: 「乙」=>想买苹果
: 而买苹果的机制如为(1)先检查有没有苹果 (2)有的话就买
: 但要让整个机制都在Critical Secion底下、就需要一个lock
: 观念是
: 「Lock资源」=>篮子
: 机制是=>谁先抢到「篮子」、就能购买
: if(篮子)
: {
: (1)检查有没有苹果
: (2)有的话就买
: }
: else //拿不到篮子的情况
: {
: 等待拿篮子、并且尝试拿取
: }
: 让我困扰的是、要制作这个Lock资源、必须要有一个具有实现lock功能的工具
: 於是我想到了MySQL的Primary Key
: 我的作法是、创造一个「MyLock」的Table
: 里面可以有很多资讯、但主要的就是要有一个LockName这个PrimaryKey
: (我这个Table其实也只放了这一个栏位)
: 所以作法如下:
: /*****Start*****/
: //买东西之前
: reslut = MySQL(insert into MyLock (LockName) value ("篮子"))
: while(result=>ErrorCode == 1062) //1062:重复的PK
: {
: //有人拿了篮子、等待一秒、之後尝试拿篮子
: sleep(1); //先等待一个时间
: result = MySQL(insert into MyLock (LockName) vlaue ("篮子");
: }
: //Critical Secion [Start]
: (1)检查仓库有没有苹果
: (2)有的话就买
: //Critical Secion [End]
: MySQL(delete from MyLock where LockName = '篮子') //释放篮子资源
: /*******End*******/
: 这个方式挺容易的
: 而且没有复杂的MySQL判断跟指令
: 另外跟原本的lock 观念也一致
: 分享给大家@@、如果我的方法有什麽问题也欢迎讨论
一个购物车,要考虑同时购买苹果香蕉橘子柳丁,以及所有水果的库存。
然後大家应该要都可以同时买东西,看来照你的作法,看来一次只能有一个人买。
如果同时三个人买,就算库存足够,也得等 (是吗?)
--
The Internet: where men are men, women are men, and children are FBI agents.
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 202.89.121.16
1F:推 sunz5010:疑、你说的对ㄝ~我是没有考虑到你这个问题 03/25 12:48
2F:→ sunz5010:不过我想、这也是可以在Critical Section那边去抉择 03/25 12:48
3F:→ sunz5010:决定一次处理多少的量、不过这个问题或许也牵扯到服务 03/25 12:49
4F:→ sunz5010:等待的问题、我在想这个或许是另外一个议题 03/25 12:50
5F:→ sunz5010:因为LOCK是一个观念、至於你要怎麽运用这个LOCK 03/25 12:50
6F:→ sunz5010:也要看你演算法怎麽设计、不过你点醒了我没注意到的地方 03/25 12:51
7F:→ sunz5010:还谢谢你的提醒@@ 03/25 12:51
※ 编辑: roga 来自: 202.89.121.16 (03/25 16:00)