冬瓜头 发表于 2010-01-13 22:24

原帖由 sunsroad 于 2010-1-13 12:32 发表 http://bbs.chinaunix.net/images/common/back.gif
我到,明显的概念混乱。

我想问一下:TCP的ack跟数据库的commit之间有什么关系呢?TCP的ack只表示客户端的TCP包传输到了服务器而已,跟数据库是否commit成功根本没有任何关系。怎么能说收到TCP ack就表明commit成功了呢?

你在客户端所谓的commit只是个commit请求,请求发送之后,他要在这里等待server端的相应结果的,成功与否并不在这里。随后的TCP sent及ack过程只表明你的commit请求已经发送到了服务器端。需要server端进行真正的commit操作。如果成功,server端才会回送成功反馈,这次是client的commit需要的“ack”,此“ack”非彼“ack”,是应用层(或者说是业务层)的ack,是放在tcp有效载荷内的数据信息。这个ack开始发送的时候,client端的应用还在等待commit请求的结果信息呢。之哟client端接受到这个相应,你的存折才会打印出那个可怜的余额+5来,所以顺序很重要,不要搞颠倒。如果这个时候DB down机,TCP再怎么ack都没有用处,client就会挂在这里等待。应用做的好的话,会在一定的时间之后超时。

过程:


你交了钱
然后等待
client |
         |
app->|->commit request->wait                                       |
         |                TCP->sent                                             |
         |                                                               recieve |Server
         |                                                             ack<-TCP |
         |                                                             commit   |
____________________________________________你所讲的步骤只到这里,如果不成功就会挂再在这里,根本你的存折没有+5,这个时间你还在这里等待来。再说如果数据库down机的话,估计你也查不了你的余额了
         |                                                commit succesful |
         |                                                 sent<-TCP(succ)|
app<-|recieve                                                               |
         |TCP->ack                                                            |
         |commit request->commpleted                              |
client|                                                                            |
这个时候,你的余额加那可怜的5块钱才能打印出来,兄弟你现在才能去查余额啊。之前的这段时间让柜台小姐帮你代劳好了。


很多时候的问题其实都是沟通问题,就像本贴中的例子。非常感谢这位兄弟的回帖,还画了图,我都不知道说什么好了,哎,浪费您劳动力了,是在感觉非常惭愧,不过你真的误会我的意思了,或者是我表达有问题。其实1楼里之所以用了tcp什么ack的,只是想表达db只要收到了这个ack,就可以放心的认为成功通知到了app,但是db没有收到。(这是原例子中的假设,后来被指出是错误的,db是先自己做commit之后,即便没有成功的通知app,也不会回退了,这一点我原来搞错了的,后面帖子都纠正了)。所以这里大可不必再缠绕在tcp层了。

bbjmmj 发表于 2010-01-13 22:31

原帖由 冬瓜头 于 2010-1-11 23:22 发表 http://bbs.chinaunix.net/images/common/back.gif
以下纯属虚构如有雷同请对号入座。


某日我去银行存捡来的5块钱,操作员拿着我的卡和现金,鄙视的看着我,我没什么感觉,习惯了。当他刷卡之后,点击输入金额5,点击存入之后,数据发送到应用服务器,应用服 ...

金融交易出错的几率是非常高的,我自己就遇到过,前段时间买股票,不小心全仓吃进,交易无法撤销。银行存取款也一样会出错,而且错误还远不止你所描述的,我记得前段时间看过一个报道,说某二人合伙利用银行转账时差套现被抓。
但是银行可以采用特定的“程序”来避免出错,比如你存款的时候柜员跟你要反复核对数次才可以完成一个存单,这就等于把错误的概率乘方好几次,这样鼓捣几下,错误的概率就会变得很小很小。前几天我汇款几万块钱,走了四个窗口才办完,手续相当繁琐,算上我等于5个人去核实这个金额,假如每人出错的概率为百分之一,5个人都错的概率就只有百亿分之一了,这个概率甚至低于最可靠的计算机出错的概率,所以保证正确的是人而不是电脑。
计算机不能保证交易的正确性,交易的处理需要人工核实其正确性。

hansion3406 发表于 2010-01-13 22:49

1.调用存钱交易
2.update数据
3.commit..
4.交易收到成功
5.返回前台
---------
6.前台打单


没有COMMIT成功之前,前台是不会收到交易成功的...

兴行做法....

hansion3406 发表于 2010-01-13 22:52

如果是数据库CORE了..
两个机子的数据是同步的...
直接启备机...
两个服务器是F5做流量...

感觉像没有出过这种问题...


其它行的做法我不知道...

但是兴行的交易存钱取钱,我还没有听过有出现你这种情况的..
PS:数据库CORE掉是不具备什么杀伤力的...

WTO432 发表于 2010-01-13 22:59

钱钱,,,,

我只知道有一个朋友在柜员机上取了一千元,吐出了一万元,后来银行找上门来了

morinson 发表于 2010-01-14 01:23

别想好事

depthblue_xsc 发表于 2010-01-14 09:15

原帖由 saintdragon 于 2010-1-13 16:40 发表 http://bbs.chinaunix.net/images/common/back.gif
我被北京的工商银行黑了2000大洋的
我存了2000大洋的房贷,通过ATM存入的,打印了凭条。2个月之后,我再次去存房贷,发现余额为0!第二天赶紧带存折去打印,存折上没有这笔存钱交易。而我当时从ATM打印的凭条已 ...

还有这种事情啊??太可怕了,银行的人按理不能直接操作数据库,流程是很严格的。

sunable 发表于 2010-01-14 11:39

不见更新,不让打票。

糊精 发表于 2010-01-14 11:52

我觉得如果能够接受数据库的COMMIT机制就应当能够理解业务的COMMIT机制。
既然显示器、内存能够和硬盘同步为什么远程设备就不行了呢。

问题在于……数据库的COMMIT机制也未必是完全原子的……

Lordaeron 发表于 2010-01-14 14:05

DB commit 表示transaction已經處理好了, 回應AP server 跟transaction就無關了
就算當下DB crash, 也無關於transaction,front end 沒收到入帳成功的message 而已.
並不影響帳目. DB recover 會在check point 中找回所有已commit的data.

so 是你的觀念有問題, 並不是存在著這樣的問題.
页: 1 2 3 4 5 6 [7] 8 9 10 11 12
查看完整版本: 银行存钱悖论探讨!!(慎入,逻辑混乱,请看完所有楼再回帖以免越弄越乱)