银行存钱悖论探讨!!(慎入,逻辑混乱,请看完所有楼再回帖以免越弄越乱)
以下纯属虚构如有雷同请对号入座。某日我去银行存捡来的5块钱,操作员拿着我的卡和现金,鄙视的看着我,我没什么感觉,习惯了。当他刷卡之后,点击输入金额5,点击存入之后,数据发送到应用服务器,应用服务器命令数据库服务器将“余额”改为“余额+5”,并且commit。数据库服务器成功的将记录更新到了磁盘并且受到了文件系统成功写入的应答,该回复应用服务器成功的消息了,commit成功的消息到达了应用服务器的tcp协议栈缓存中,并且tcp成功的返回了一个珍贵的ack应答,数据库服务器还没收到这个ack呢,便Down机了,或者收到ack了,正要往日志里更新commit成功点了,Down机了。重启之后,当然是将这笔操作回退了,数据文件中的“余额+5”变回了“余额”。但是就在几分钟之前,应用服务器早就把成功的消息传回给了操作员终端,我也拿着回执单走了。但是我回去一看,怎么余额没有增加?我气冲冲的找到柜台,依然是鄙视的眼光,操作员说:5块钱,至于么!
兄弟们,你说这5块钱,我是要还是不要呢?
本贴另一个instance:
http://www.itpub.net/viewthread.php?tid=1258488&extra=&page=1
-------------------------------------------------
例子中有一步是错误的,即db必须commit之后才会返回给操作端。所以在此对这个错误引来的不便表示歉意。而且我绝对不是在对db本身的机制质疑,二是对整体流程方面有疑问。其次,本贴确实不是什么悖论,用这个词只是为了吸引个眼球,如果觉得碍眼,请多担待。
更正一下。
如果是存钱,出现这个问题,你就赚了,相当于拿了一笔现金,操作员重复操作给存了两笔、
如果是取钱,你就亏了,重复操作的结果就是取了两次而你只拿到一笔钱。
初步讨论的结果,这种情况下人的因素很重要,要靠人来解决。
-------------------------------------------------
[ 本帖最后由 冬瓜头 于 2010-1-14 16:01 编辑 ] 你只要投诉,过几天5块钱就会到帐。因为你忽略了一个问题,你在存钱的时候填单子了。
当然也有3种情况导致你的5块钱到不了账:
1. 你忘了在单子上签名确认;
2. 签了个不是你开户时使用的名字。
2. 在银行下班前,为你办业务的银行因为火灾、地震的等原因,从地球上消失了。 无牙的意思是说这种情况无可避免么?其实我最终想了解的是,数据库就算用了日志也不能保证绝对的数据不丢失,最终还得靠回执单,实实在在的证据。 是这样的。所以银行会把凭证扫描做长期保存。
这也是为什么ATM机在操作后,会问你要不要打印凭条的原因。
如果银行觉得凭条没有用,就不打印还节约成本,谁还问你要不要。 好的,既然这样,银行存钱问题解决了。但这个结论却让我非常吃惊,后遗症很多啊,比如一些不要凭条的东西,比如某企业应用,某生产系统,不直接牵扯到钱的,你一down机就个人丢失了条数据,或者说财务还没来得及打印报表,某一笔款项记录给人丢失了,咋整?
流程不对
银行是pos终端……:mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen: 不管是哑终端还是智能终端,哑终端就能避免这个问题了么?请教楼上怎么避免的呢?有人在另一个论坛说:"或者收到ack了,正要往日志里更新commit成功点了,Down机了" 这个不可能,数据库把commit写入日至之前不可能给app发出成功的消息。
我的回答:
呵呵,首先感谢各位的关注,这确实不是什么悖论,只是吸引点眼球罢了,不必太多心。
至于步骤有错,3楼和5楼的结论是因果关系,如果我能退出3楼结论也一样会造成问题的话呢?如果说db在没有给app回复的情况下就先写入commit点,那么如果是取钱,我取走了,你余额降低了,但是打算给app回复的瞬间,链路中断或者db down,那么操作员就会认为钱没有取走,db重启后,操作员再次重试,由于操作员刚才和现在都没有对余额的变化关注过,所以再次取走了钱,也就是说,db中钱被降低数值两次,而你拿到手的钱和回执单却只有一次,损失谁来给?
而且这是银行,有回执单可以作证,如果是没有回执单的应用呢?down个机就丢一些数据,链路中断也可能丢一些数据,真不知道这样怎么行呢?
各位,这个问题我是演绎了很长时间的,我是来请大家帮忙推翻我的结论的,如果能推翻万事大吉,如果不能推翻,现实中是如何解决这的问题的呢?多谢多谢! 如果是取钱的发生这个事情就好了 呵呵,取钱一样遭殃,看发生在哪个环节了。看7楼的分析。 来学习的飘过 此帖要火