【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--

 

posted @   逆火狂飙  阅读(87)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2014-09-10 【Canvas与旗帜】红白蓝黄星正方形旗帜(用于制作120*120图标)
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示