理解跨系统之间金额的业务调用的资金平衡结算程序和过程

    对于跨系统调用,它和同一个系统调用多个数据库不同,在两个系统调用之间,会出现各种各样的问题,导致会发生数据不一致的问题存在。本文从系统之间调用出发,并结合类金融系统的资金实现样例,来解析这种业务的实现过程。

    我们现在有两个系统,A系统为金额系统,负责金额数据的存放和结算,当进行充值和消费时,将对金额的数据发生变化;B系统为业务系统,负责处理消费业务的实现,但当进行实现时,需要发送消费数据信息到A系统进行金额数据的存储,待存储完成之后方能进行下一步的业务流程。

    可以由下面的一个流程来理解两个系统之间的交互:

  1. B系统发起消费业务,负责业务实现前的验证
  2. 验证成功,B系统向A系统申请付款信息
  3. A系统验证确定可以付款,产生付款信息,并进行金额结算
  4. A系统返回应答信息,B系统继续进行业务操作,完成消费业务实现

    在以上的四个操作中,任何一步都可能发生错误,而且在系统与系统之间的交互过程中,还存在着网络方面的问题。当网络中断时,整个交互过程也不能完成。

    首先可以肯定的是,这并不是一个事务内的事情,A系统和B系统是两个独立的系统,在网络上独立,且系统与系统间数据库是不会互相开放的,所以想在一个事务内考虑问题,是不能成功的。只从从系统外,即如何保证两个系统之间的数据平衡。

    对于这种情况,只能通过流水号对账,双金额的收支平衡来解决此问题。即在A系统中设定一个预付金额和确认金额,B系统设定业务流水号,AB系统定时通过流水号进行帐务结算。对错误的业务信息,进行冲帐,正确的业务信息进行确认。

    简单介绍下实现,在B系统中有一个业务流水号,记录着每一笔交易信息;A系统中有两个金额,一个是预付金额,一个是确认金额,预付金额用于在B系统进行业务处理前,记录业务交易的金额数据,确认金额用于在B系统业务处理后,记录业务交易的确认数据。一般情况下,预付金额与确认金额一致。此外,A系统同时记录B系统的业务流水号,以便于定时进行业务对帐。
    业务对帐,表现确认两边的数据是否一致,同时对未写入的确认金额进行确认或取消。当业务一致时,确认金额表现为交易金额数据,当业务不一致时,预付金额表现为需要冲正的金额数据,将在进行对帐时进行处理。
    详细数据结构如下:
A系统:

bId (B系统业务流水号)
preMoney(预处理金额)
confirmMoney(确认金额)

B系统:

bId(B系统业务流水号)
aId(金额处理流水号,可选)

继续阅读“理解跨系统之间金额的业务调用的资金平衡结算程序和过程”

fedora15中在gcc4.6环境下安装oracle10g

    升级到fedora15之后,本来想安装oracle 10g进行项目开发。待下载了oracle 10g之后,直接按照原来的安装模式进行安装。即像fedora14中安装一样进行安装,如 http://www.iflym.com/index.php/linux-develop/install-oracle10g-on-fedora14-or-centos5-5.html。然后在安装过程中,即报了如下一个错误:错误如下所示:

"Unrecognized option (gcc) -no_cpprt"

    错误发生在oracle安装大概63%过程当中。网上找了半天,原来即是gcc4.6之后,已不再支持no_cpprt选项,而在gcc3.X上,此命令也是正确的。那么即可安装gcc3.X版本,进行安装。但实际上并不需要降级安装gcc3.X,而只需要安装compat-gcc-34。如下所示:

yum install compat-gcc-34

    在安装之后,即会在/usr/bin下有一个gcc34的命令,此命令即可接受no_cpprt选项,实际上即是gcc3.X的兼容命令。现在只需要将gcc转换为gcc34即可。详细命令如下:

mv gcc gcc46
ln -s gcc34 gcc

    这只是将gcc 4.6版本暂时替换成gcc34版本,现在再进行安装,oracle 10g即安装成功了。接下来即是和原来的使用一样了。待安装完成之后,再将gcc原来为gcc46即可。

解决oracle中使用hibernate在某些条件下不能正确创建hibernate_sequence的问题

    项目中使用了ssh作为开发底层框架,由于在开发前期并没有限制项目运行在哪一个数据库之上,因此在hibernate的配置上使用Generated的id生成方式,使得能够在不修改源代码的情况下,无缝的在不同的数据库上跑,只需要修改配置文件中的dialect即可。
    在这种情况下,在oracle中,hibernate就会使用一个叫做hibernate_sequence的全局sequence来作为所有主键的生成sequence,在新增一条记录之上,均需要从此sequence中取一个数值,并作为其他记录的主键插入到数据库当中。

    然后,这个hibernate_sequence并不是在项目启动之前手动地创建的,而是使用了hiberante的create-update方式,即创建-修改的方式进行创建。既然是这样,那么hibernate在启动之前即需要去检测所要创建的sequence是否存在,如果存在,则不再创建此sequence。然而,在某些情况下,hibernate能够探测到其它用户所创建的sequence,而被认为不再需要创建sequence,这时候就会在项目运行中出错了。出错的原因,即找不到相应的sequence。
    这个错误和hibernate不会主动创建某些表一致,不一样的是hibernate用的是另一个判断语句来判断相应的sequence是否存在。
    相关链接:解决在oracle数据库中使用hibernate生成表不能正确创建表的问题.

继续阅读“解决oracle中使用hibernate在某些条件下不能正确创建hibernate_sequence的问题”

解决在oracle数据库中使用hibernate生成表不能正确创建表的问题

    最近在项目中使用hibernate的动态生成表,即将hbm2ddl.auto配置成update时,发现hibernate并没有按照默认的生成规则生成相应的数据表信息。但奇怪的是,只是部分表没有生成,而其它的表即生成成功了。重新启动项目,发现问题依旧。奇怪的是,虽然有些表没有生成,但它相关联的关联表即生成了,而且在生成时,会报一个找不到相关的引用表的错误。报的错误如下:

=2011-05-06 09:45:56 [org.hibernate.tool.hbm2ddl.SchemaUpdate]-[ERROR] Unsuccessful: alter table r_role_x_menu add constraint FK474DC862E1A553E2 foreign key (menu_id) references p_menu
=2011-05-06 09:45:56 [org.hibernate.tool.hbm2ddl.SchemaUpdate]-[ERROR] ORA-00942: 表或视图不存在

    找了半天,最后发现一个问题,即这里需要引用的表p_menu在另一个用户空间里已经存在了,而hibernate在创建表时,在另一个用户空间中找到了这个表,故不再在当前的用户空间中创建这个表了。而在创建关联表时,由于关联的是本用户空间的表,故有此错误。
    hibernate使用了jdbc默认的databasemeta来寻找相应表数据信息,当使用默认的配置时,由于某种原因(并不是每次都能发生,取决于数据库本身以及相应的驱动)。当使用当前用户连接到数据库时,使用databasemeta寻找数据库表信息时,会查询出其它用户的数据表信息(即使当前用户没有相应的权限)。
    解决此问题的方法很简单,只需要在hibernate.cfg.xml中配置一句:

<property name="default_schema">当前连接用户</property>

   这样,使用databasemeta时,就会强制性地在当前用户空间中寻找数据库信息了,这样就能正确的创建出表结构了。

在Fedora14上(或CentOS 5.5上)安装oracle 10g

     新安装了一个fedora14,所以想把oracle给装上去,网上看了很多例子,再结合自己安装的实际操作,将整个过程记录下来,给其它想安装的人一个详细的过程。本安装过程以fedora14,oracle10g为准。所以,如果不是这个版本的话有些地方可能有差异。

继续阅读“在Fedora14上(或CentOS 5.5上)安装oracle 10g”