有一次我在东莞,我的同事在去东莞的途中,手机没钱了,让我帮忙买两张充值卡,我便卖了两张100的并把卡号密码用短信发了过去。不久他就到了东莞,我才知道他要给自己和女朋友的手机充值,他的手机是广东的,充值没有问题,但是她女朋友的手机是江西的,则出了点问题。广东这边提示已经充值成功,那张卡也提示已经使用了,但是江西那边手机上根本没有收到钱。最离谱的是,这充值卡上本来就说明了只能给广东用户充值,不能异地充值。
我的同事去移动投诉,可是没有头绪,广东这边记录的是充上了,但是江西那边一无所知。其实有这样的结果我也有所预期,因为对于异地业务,移动是通过总公司的作为中转实现的,整个过程稍微有点复杂。对于上面说的异地缴费,首先是广东这边发起一个交易到总公司,然后总公司联系江西完成这个充值,然后和总公司确认,总公司再和广东确认。上述过程的每一步操作都是异步的,如果出现异常状况,就要靠事后比较日志进行核对。事实上,经常会有不一致的地方,需要事后处理。
根据一般用户的感觉一定会问,都是移动公司,怎么异地充值还这么麻烦啊?主要是各个省的系统都是独立的,具体为什么系统都是独立的呢,有很多原因,但是目前的局面有好处也有坏处,好处就是有广东和广西移动公司为了争取全国市场推出了许多漫游费很便宜的sim卡,坏处就是根本就不应该有的漫游费。但是对于这种跨地市的业务,总公司的做法是很正确的:制定统一的接口标准,建立一个总的服务,分发跨省的业务。这非常符合现代服务总线的要求,例如避免了各个省的集成(34!可不是小数目),虚拟的服务地址,各个省只需要和总公司打交道就行了。
不过在这种跨系统的事务处理上,我感觉还是有点问题。例如我朋友的这个充值,钱是交给了广东移动,而对应的江西移动应该办事(例如缴费开机),但现在的状况就是交钱了,但是没有业务,整个事务不一致了。这源于原来的架构并没有一个一致的事务处理机制,我们无法和本地系统编程一样声明一个事务,最后关掉了事,因为充值可能需要几分钟的延迟,我们不能锁定所有的资源等待事务完成。
类似的情况还有银行的转帐以及银行的中间业务。因为涉及到两个独立的系统,所有的操作需要有一个记录,如果没有得到正确的响应,则能够回退所作的操作。在以前,对此类问题的常见解决办法就是建立一个表,记录了所作的业务操作,并设置一个标记,根据具体情况确认业务或者回退。
但是,现在的业务越来越复杂,这类业务越来越多,编写这样的程序耗费了大量的精力。一旦发生错误,就会在处理错误时又造成了许多维护负担,所以非常需要一种一致性的处理方式。在BPEL中提出了异常和补偿处理,对于上述情况,也就是可以定义一个补偿事务,保证如果发生错误也可以象事务一样,将充值卡恢复到正常的状态。当然这种特性还正在摸索阶段,各个厂商处理的方式并不一样,但的确可以省掉许多自己处理的麻烦。如果我们的ESB或者其他服务能够顺畅的执行这种补偿服务,我们就可以放心的编写更多的跨系统的、需要事务的,但是时间较长的业务了,而无须小心谨慎的处理异常情况。关于这补偿事务的介绍可以看:
- http://www.oracle.com/technology/global/cn/tech/soa/mastering-soa-series/part3.html
http://www.oracle.com/technology/global/cn/architect/soa-suite-series/wli-bpel-transactions.html
不过想了这么多,其实可能就是程序有问题,因为那个充值卡可能真的和广东移动所称的那样,只是一张本地的充值卡,所以不能给异地的手机充值,它的流程到营业厅所做的异地充值并不一样。不过,无论什么事情,一旦跨系统就会麻烦很多,这是不可避免的,只是希望现在的中间件能够最大程度的简化其中的复杂性。
以下链接有最新ORACLE中间件的资料可以去看看:
Related posts:
4 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.
汗~
嗯,我也汗
Oracle融合中间件在行业扮演领导角色
以前接触过WebLogic,现在却在用Oracle。