使用JOTM为Servlets增加事务支持(2)

应用程序设计

数据层

在数据层,我们需要两个不同的数据库,在每个数据库中都存在一张表。为了让例子更加真实,我们会使用两个不同的数据库,因为从不属于用户账户所在银行的ATM上取钱是确实可能出现的情况。(根据以下信息配置数据库)

banktest包括account表,表示用户账户信息。

atmtest包括atm表,表示ATM信息。

 

逻辑层

在逻辑层,我们有三个类访问资源并在资源上进行各种操作:

foo.BankAccount表示指定用户的银行账户并通过JDBC对数据库中的account表进行操作。

bar.ATM表示ATM并通过JDBCatm表进行操作。

bar.CashDelivery使用上面两个类完成用户取钱的操作。

所有的逻辑都在CashDelivery.java类的deliverCash方法中完成。

javax.transaction.UserTransaction接口被用来指定是否使用事务,所有在utx.begin()utx.commit()(或者utx.rollback())之间的操作都会在一个事务中完成。这就保证了你的Web应用不会陷入上面的场景所讨论的痛苦之中。

感谢事务,让应用的逻辑变得如此简单,仅仅包括如下几步:

1)开始事务;

2)与用户的银行联系,并从账户上支取相应的数额;

3)告诉ATM提供现金;

4)结束事务

a)      如果所有的事都成功完成,那么提交事务;

b)      否则,回滚事务

5)将事务的结果向用户报告。如果事务成功完成,那么用户得到现金,并且账户上会扣除相应的数额。否则,什么事都不会发生。

示例一

CashDelivery.java

public boolean deliver(String client, int value) {
    
    
    InitialContext ctx          = new InitialContext();
    
    
    UserTransaction utx = (UserTransaction)
    
    
    ctx.lookup("java:comp/UserTransaction");
   
   

   
   
    
     
   
   
    ...
    
    

   
   
    
     
   
   
    boolean success = false;
    
    
    try {
    
    
        // 开始事务
    
    
        utx.begin();
   
   

   
   
    
     
   
   
        // 与用户开户银行通信...
    
    
        BankAccount account = new BankAccount(client);
    
    

   
   
    
     
   
   
        // ... 并从账户上扣除相应的数额.
    
    
        account.withdraw(value);
    
    

   
   
    
     
   
   
        // 联系ATM...
    
    
        ATM atm = new ATM();
    
    

   
   
    
     
   
   
        // ... 提取现金给用户.
    
    
        atm.deliverCash(value);
    
    

   
   
    
     
   
   
        // 所有事情都成功完成.
    
    
        success = true;
    
    

   
   
    
     
   
   
    } catch (Exception e) {
    
    
        // 有错误发生
    
    
        // 必须向用户提供信息
    
    
        explanation += e.getMessage();
    
    

   
   
    
     
   
   
    } finally {
    
    
        try {
    
    
            if (success) {
    
    
                /* 所有事情都成功完成, 我们提交事务.
    
    
                * 只有在现在, 用户账户上才真正扣除相应的数额,
    
    
              * 并且现金被送到用户手中     
    
    
                */
    
    
                utx.commit();
   
   

   
   
    
     
   
   
            } else {
    
    
                /* 有错误发生, 我们回滚事务.
    
    
                * 任
    
    
    
    
     
     何
    
    在事务中进行的操作都不会真正发生
    
    
                */
    
    
                utx.rollback();
   
   
            }
    
    
        } catch (Exception e) {
    
    
            /* 在事务完成过程中有错误发生
    
    
            * 我们仍然保证在事务中进行的操作不会真正发生
    
    
            */
    
    
            // 我们必须向用户报告有关信息
    
    
            explanation += "/n" + e.getMessage();
    
    

   
   
    
     
   
   
            // 最后,事务没有成功
    
    
            success = false;
    
    

   
   
    
     
   
   
        } finally {
    
    
            return success;
    
    
        }
    
    
    }
    
    
}
  
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值