`
weibawoaini
  • 浏览: 19584 次
  • 性别: Icon_minigender_1
  • 来自: 四川
社区版块
存档分类
最新评论

论转帐业务的两种实现方式

阅读更多
                           论转帐业务的两种实现方式
要实现银行系统的转帐业务咋看很简单,无非就是转出的帐号减去转出的钱,转入的帐号加上转入的钱就行了。可是问题没有想象的那么简单,那么这里我就来说说银行转帐业务的大致流程。由于本人用的是Java语言,所以也就谈Java的方法,若有其他语言版本的同仁,此法仅供参考。
那么究竟是哪两种方式呢?
先介绍下数据库的表结构:用户表(用户ID、帐号、用户名)、操作表(操作表ID、操作业务类型、用户ID、操作日期)、操作明细表(明细表流水号、操作表ID、操作Money、操作说明(如转入/转出多少钱)、用户ID)。
一种是用纯Java OO的思想来完成转帐业务,所有的业务处理和事物控制过程全部在Java实现;另一种是用数据库实现(Oracle),业务处理和事物的控制权不都在数据库内实现——即用存储过程加函数。
下面我就这两种不同的方式做一个简单比较。
如果是第一种方式来实现转帐业务的话,那么肯定是用到经典的MVC模式,将整个系统分为模型-视图-业务控制等几个层,不用说大家都知道,模型层主要是一些简单的javabean,是和我们数据库想对应的一些简单Java对象,也就是我们每个表的Java抽象。视图层,顾名思义就是用来给用户展示数据信息的层,主要是一些jsp或者html等网页。当然,最难的是业务控制部分,在这部分,我们可能会有ActionServlet.java这个中央控制的Servlet类,还需要专门用于业务操作的Servicel类,以及数据持久化的Dao等众多类组成。其中又会抽象出很多的接口,这样是利于后期的维护与新的需求。加起来实现转帐业务的话大概需要10多个类,相对来说步骤比较繁琐,下面我们看看数据实现方式。
            而如果用数据库(前提是用Oracle)来实现转帐业务的话,想对来说步骤没那么简单。但是与第一种方式同样重要的一点就是,开发人员必须对整个业务流程非常的熟悉,因为所有的业务我们会在一个存储过程中去完成,具体实现代码我会在下面贴出。而Java只需调用存储过程就能完成整个业务的流程控制,相对来说开发步骤少了很多,而Java也不需要写很多类和接口,但是这样会出现一个很大的弊端,就是后期的维护性很差。因为我们在一个存储过程中实现所有业务的话代码会相对较长,一般只有编写代码本人能够看懂,一旦出现问题,维护是就是一件很伤脑筋的事情。而Java OO实现的方式在维护上就轻松得多,就算业务有变更,因为我们之前有很多的接口,所以也不需要修改原有的代码便能增加新的业务,而第二种方式是不可能的,必须要修改存储过程的代码,而这又是一件头大的事情。所以大多数情况下企业还是会选择前面那种开发方式。那为什么还是有用第二种方式开发的呢,原因很简单,因为存储过程开发的话程序的运行效率要比前者高很多,所以在有的时候考虑到大数据量的时候,效率才是关键问题,这也是移动、电信开始想第二种方式靠拢的原因吧。
那么我们到底应该如何选取开发的方式呢?
           下面仅供参考意见,如果业务经常有变更,或者说经常有新的业务需求的话,我觉得最好用第一种开发方式,因为这样便于维护。如果说业务相对较为固定而你又要求效率的话那么可以考虑后者。

下面是存储过程的代码:
CREATE OR REPLACE PROCEDURE SP_TRANSFER(P_ACCOUNT_OUT T_ACCOUNT.A_ACCOUNT%TYPE,
                                        P_ACCOUNT_IN  T_ACCOUNT.A_ACCOUNT%TYPE,
                                        P_MONEY       T_ACCOUNT.A_BALANCE%TYPE) AS
  V_ACCOUNTCOUNT NUMBER(1);
  V_BALANCE      T_ACCOUNT.A_BALANCE%TYPE;
BEGIN
  SELECT COUNT(A_ACCOUNT)
    INTO V_ACCOUNTCOUNT
    FROM T_ACCOUNT
   WHERE A_ACCOUNT = P_ACCOUNT_OUT;
  IF (V_ACCOUNTCOUNT = 0) THEN
    RAISE_APPLICATION_ERROR(-20001, '转出账户不存在!');
  END IF;
  SELECT COUNT(A_ACCOUNT)
    INTO V_ACCOUNTCOUNT
    FROM T_ACCOUNT
   WHERE A_ACCOUNT = P_ACCOUNT_IN;
  IF (V_ACCOUNTCOUNT = 0) THEN
    RAISE_APPLICATION_ERROR(-20002, '转入账户不存在!');
  END IF;
  SP_ADD_OPERATION(3, P_ACCOUNT_OUT);

  SELECT A_BALANCE
    INTO V_BALANCE
    FROM T_ACCOUNT
   WHERE A_ACCOUNT = P_ACCOUNT_OUT;
  SP_ADD_OPERATION_DETAIL(V_BALANCE,
                          '账户:' || P_ACCOUNT_OUT || ',查询余额');
  IF (P_MONEY > V_BALANCE) THEN
    SP_ADD_OPERATION_DETAIL(V_BALANCE,
                            '账户:' || P_ACCOUNT_OUT || ' ,余额不足'||P_MONEY||'元,转账失败');
    SP_OPERATION_SUCCESS_OR_FAILED(0);
    RAISE_APPLICATION_ERROR(-20003, '余额不足' || P_MONEY || '元!');
  ELSE
    UPDATE T_ACCOUNT
       SET A_BALANCE = A_BALANCE - P_MONEY
     WHERE A_ACCOUNT = P_ACCOUNT_OUT;
 
    SP_ADD_OPERATION_DETAIL(-P_MONEY,
                            '账户:' || P_ACCOUNT_OUT || ',转出金额');
 
    UPDATE T_ACCOUNT
       SET A_BALANCE = A_BALANCE + P_MONEY
     WHERE A_ACCOUNT = P_ACCOUNT_IN;
    SP_ADD_OPERATION_DETAIL(P_MONEY,
                            '账户:' || P_ACCOUNT_IN || ',转入金额');
    SP_OPERATION_SUCCESS_OR_FAILED(1);
    COMMIT;
  END IF;
END;
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics