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