p*****c 发帖数: 2858 | 1 大家好,小弟最近开发一个库存系统的时候,遇到了一点点技术瓶颈,无奈小弟才疏学
浅,百搜不得其解,只好来这里向大家讨教了。
数据库用的是mysql。
比如说,我有一个表存放库存数据,就简单两个字段product id与quantity;
卖出去了,就
1.begin transaction;
2.update quantity=quantity-1;
3.commit;
退回来了,就
1.begin transaction;
2.update quantity=quantity+1;
3.commit;
当负载量很低时,这样是没问题的。
但是一旦需要并发操作,就会发现事务处理不生效。
比方说,有一个产品,原有quantity 100。这时同时导入了3个订单,各订购一个,结
果quantity 就是99.而不是97.
想请问大家一般遇到这种应用的时候,是怎么设计语句的?
或者有没有什么机制可以避免?
我一直很好奇amazon/bestbuy的库存系统是怎么做的,但是无奈没有相关资料。
恳请指点迷津。
谢谢 |
a9 发帖数: 21638 | 2 你这个表不是这么简单吧。你的语句也可能不是这么简单。
【在 p*****c 的大作中提到】 : 大家好,小弟最近开发一个库存系统的时候,遇到了一点点技术瓶颈,无奈小弟才疏学 : 浅,百搜不得其解,只好来这里向大家讨教了。 : 数据库用的是mysql。 : 比如说,我有一个表存放库存数据,就简单两个字段product id与quantity; : 卖出去了,就 : 1.begin transaction; : 2.update quantity=quantity-1; : 3.commit; : 退回来了,就 : 1.begin transaction;
|
p*****c 发帖数: 2858 | 3 对,不过多出来的字段和这个问题无关。
而因为用了ORM之后,所有的sql语句都被抽象化了。
出现问题我调试的时候,是把最基本的sql都打印出来查看,然后就归纳成这几条了。
我现在突然觉得,是不是因为,update数据的时候我没有给这个表上锁所以才会出这个
问题。
但是如果上read lock。估计整个系统都会瘫痪吧,因为很多其他需要读取库存数据的
进程很多啊。
【在 a9 的大作中提到】 : 你这个表不是这么简单吧。你的语句也可能不是这么简单。
|
i*******d 发帖数: 81 | 4 write lock吧。
几个update不能同时写。
【在 p*****c 的大作中提到】 : 对,不过多出来的字段和这个问题无关。 : 而因为用了ORM之后,所有的sql语句都被抽象化了。 : 出现问题我调试的时候,是把最基本的sql都打印出来查看,然后就归纳成这几条了。 : 我现在突然觉得,是不是因为,update数据的时候我没有给这个表上锁所以才会出这个 : 问题。 : 但是如果上read lock。估计整个系统都会瘫痪吧,因为很多其他需要读取库存数据的 : 进程很多啊。
|
s**********o 发帖数: 14359 | 5 很明显,你不是科班出身,学过操作系统的都知道这个WRITE LOCK的,
当你RUN update quantity=quantity-1;其它的UPDATE只能等到TRANSACTION
COMMIT之后才能接着RUN,所以最后是97而不是99,
注意你的BEGIN TRAN是多余的,你就一个UPDATE在里面,已经内涵的BEGIN TRAN了,
BEGIN TRAN是这样用的
BEGIN TRAN
UPDATE TABLE 1
INSERT TABLE 2
DELETE TABLE 3
..
COMMIT TRAN |
a9 发帖数: 21638 | 6 他现在是结果是99,而不是97
是不是update quantity=quantity-1是分两步,select再update?
【在 s**********o 的大作中提到】 : 很明显,你不是科班出身,学过操作系统的都知道这个WRITE LOCK的, : 当你RUN update quantity=quantity-1;其它的UPDATE只能等到TRANSACTION : COMMIT之后才能接着RUN,所以最后是97而不是99, : 注意你的BEGIN TRAN是多余的,你就一个UPDATE在里面,已经内涵的BEGIN TRAN了, : BEGIN TRAN是这样用的 : BEGIN TRAN : UPDATE TABLE 1 : INSERT TABLE 2 : DELETE TABLE 3 : ..
|
s**********o 发帖数: 14359 | 7 那就是他的APPLICATION写的有问题,3个CUSTOMER一起UPDATE,应该有三个THREADS吧,
每一个都是独立的TRANSACTION, 一个UPDATE就是一个TRASACTION, SELECT不是个
TRASCATION,
他可能有UNCOMMITED TRANSACTION
【在 a9 的大作中提到】 : 他现在是结果是99,而不是97 : 是不是update quantity=quantity-1是分两步,select再update?
|