zoukankan      html  css  js  c++  java
  • 【RabbitMq/Springboot】给跨库转账增加回访以提高安全性

     转账主动端例程下载:https://files.cnblogs.com/files/heyang78/myBank_tranfer_active_210910.rar

    转账被动端例程下载:https://files.cnblogs.com/files/heyang78/myBank_transfer_passive_210910.rar

    前作 中提到,如果跨库转账,对方库不存在账户,则转出账户的钱就消失了,为了解决这个问题可以增加一个队列queue02,让远程库把反馈发还回来。

    比如说,本地库有个账户001,想给对方库不存在的账户009转账500,于是将“001/009/500”的消息发给queue01,对方发现不存在009,数据库更新记录为零后,就将001/500的信息发给queue02,本地库发现后将001的余额加上500,等于退回了001转出的金额,这是对方不存在的情况;而001想给对方库存在的账户002转500,于是将“001/002/500”的消息发给queue01,对方数据库更新记录为一后,将001/0的消息发给queue02,本地库发现后将001的余额加上0,等于确认了001转账的结果。整个闭环就完成了。

    为完成这个闭环,RabbitMq里需要增加一个队列queue02.

    转账主动方发送消息部分·:

    @Component
    public class AccountService {
        @Resource
        private AccountMapper amapper=null;
        
        @Autowired
        private RabbitMqMsgSender mqSender;
        
        @Transactional(rollbackFor=Exception.class) 
        public void remoteTransfer(int amount,String fromAccount,String remoteAcccount) throws TransferException{
            int count=amapper.add(-amount, fromAccount);
            if(count==0) {
                throw new TransferException("对转出账户:"+fromAccount+"操作,更新记录数为0.只有可能是该账户不存在。");
            }
            
            String msg=fromAccount+"/"+remoteAcccount+"/"+amount;
            mqSender.send(msg);
            System.out.println("已向queue01发送消息:"+msg);
        }
    }

    被动入账方接收消息部分: 

    @Component
    @RabbitListener(queues="queue01")
    public class RabbitMqMsgReceiver {
        @Resource
        private AccountMapper amapper=null;
        
        @Autowired
        RabbitMqMsgSender q02Sender;
        
        @RabbitHandler
        public void QueueReceive(String receivedMsg) {
            System.out.println("T14收到来自queue01的消息:"+receivedMsg);
            
            String[] arr=receivedMsg.split("[//]");
            String fromAccount=arr[0];
            String toAccount=arr[1];
            int amount=Integer.parseInt(arr[2]);
            
            int count=amapper.add(amount, toAccount);
            String msg="";
            if(count==1) {
                msg=fromAccount+"/0";// 表示账户存在,退回金额自然为零
            }else {
                msg=fromAccount+"/"+amount;// 账户不存在,金额全部退回
            }
            
            q02Sender.send(msg);
            System.out.println("T14向queue02发送消息:"+msg);
        }
    }

    转账主动方获取反馈消息部分:

    @Component
    @RabbitListener(queues="queue02")
    public class RabbitMqMsgReceiver {
        @Resource
        private AccountMapper amapper=null;
        
        @RabbitHandler
        public void QueueReceive(String receivedMsg) {
            System.out.println("T440p收到来自queue02的消息:"+receivedMsg);
            
            String[] arr=receivedMsg.split("[//]");
            String toAccount=arr[0];
            int amount=Integer.parseInt(arr[1]);
            
            amapper.add(amount, toAccount);
        }
    }

    当然,这个程序还没有考虑宕机的问题。

    --END--

  • 相关阅读:
    Thinking Clearly about Performance
    国家统计局2018-10-30统计的最新的省市区
    Java 返回字符串中第一个不重复字符的下标 下标从0开始
    国际象棋的游戏规则
    Python语言之requests库
    VBS 自动发消息给对方
    Windows
    上海合计共有16个区一个县
    @RequestMapping中的注解
    Linux 中 /proc/kcore为啥如此之大
  • 原文地址:https://www.cnblogs.com/heyang78/p/15253087.html
Copyright © 2011-2022 走看看