问题描述:
今天为校园卡充卡时发现的现象,学校里有可以为校园卡充值的终端,在充值之前卡里有20块钱,然后先去食堂刷卡买饭,刷掉了8元(即剩下12元),然后去终端进行冲卡,充入50元,查询余额显示70元,但是在食堂的刷卡机里显示的是62元,这是怎么回事呢?
本人的考虑:终端处进行的充值操作即update,未进行事务提交,而在食堂中进行的操作都是立即进行提交操作,二者访问的是同一数据库实例,在终端处的未设置事务立马提交的考虑在于终端处的业务大部分都是充值缴费,对实时性要求肯定不如食堂刷卡要求高,可以设定在午夜进行当天信息的提交,避免针对数据库的I/O操作,造成数据库性能下降。问题在于,终端数据在更新的时候是以哪里的数据作为最新的数据进行的呢?在充值结束之后,存在校园卡消费的情况下,如何保证数据的正确性?
------解决思路----------------------
出现这种情况感觉不太正常。我觉得最好应该是按照银行的模式来设置。
我觉得两地方访问的是不同的表或者实例。
如果是访问的同一实例,当你刷卡以后,事务提交,数据一致。充值的时候,应该是在历史数据的基础上+50.
感觉系统的处理机制的是,每天晚上会将刷卡记录(消费)继续一次处理(数据同步),然后保证数据一致。
------解决思路----------------------
这要看是什么卡机和什么卡片了.
大概流程:
1.消费时的卡机,数据不是实时更新数据库的,只有在某个时间时才上传到服务器,然后再读到数据库的,也是流水记录.然后再根据所有的流水记录更新你的账户金额.你的卡上有20元,消费8块,还有12元,但这次消费没有更新数据库,消费记录没有插入数据库.
2.冲值的卡机有连一台电脑,数据会实时插入到数据库并提交的,并且会插入一条流水记录.所以它在冲值前会找你在数据库中的金额是50(那8块钱还没有更新),然后再冲20,就是70.
3.你的卡片其实是有记录功能的,可以记录最近几次的消费记录和余额,在消费卡机上刷时一计算就是62了.
以上是我猜的,哈哈
------解决思路----------------------
你想得太复杂了 。你所在学校一卡通消费系统是以卡为主。卡上存储了你的余额。你之前消费的终端设备,已经将你卡里扣除了8块钱。只是消费流水没有及时上传到数据库服务器。所以导致你在数据库服务器所在的系统查询到得数据是你消费之前的余额。你在消费终端上贴卡读得是你的卡余额。与系统余额有可能存在不一致。如果发现这种情况。就是说消费终端没有联机。你可以办一张临时卡。充值200,块钱。在发现没联机的设备上消费200元。然后将你的卡挂失。然后补卡。你会发现你的卡里又有200元。这是件很惊喜的事情哦。
------解决思路----------------------
觉得事物处理太多了,没必要充值的时候访问另外一个同步表吧。
从我的角度来看,充值要完成的事物远远小于刷卡买饭需要的事物,完全没必要同步数据库。
就这个来说的话,应该是某一个时间点同步数据库。