远程调用历史及代码编写demo
@Transactional
public void tixian(OrderInfo orderInfo){
try {
OrderVO order = new OrderVO();
order.setAmount(orderInfo.getAmount());
order.setId(orderInfo.getId());
order.setName(orderInfo.getName());
//调用远程接口,从用户账号扣款,转账到自己账户
//此处response只是模拟写法,具体要参照api来写,而且此处可能有异常,该处的异常暂不考虑
//此处认为,response为null是网络异常的情况
BankResponse response = bankService.moneyOut(order);
//根据远程接口返回的状态,判断是否支付成功
if(response !=null && response.getCode().equalsIgnoreCase("s")){
orderInfo.setStatus(2);//支付成功
}else {
orderInfo.setStatus(3);//支付失败
}
//保存订单状态
orderInfoDao.updateByPrimaryKey(orderInfo);
}catch (Exception e){
e.printStackTrace();
}
}
BankService是个远程接口,本地demo配置为:
<bean name="bankService" class="com.istack.base.httpService.client.HttpProxyFactoryCglib">
<property name="targetClass" value="com.xxx.bank.BankService"></property>
<property name="endPoint" value="http://localhost:18080/rpcTest"></property>
<property name="timeOut" value="35000"></property><!--超时会返回null-->
</bean>
OrderInfo的status,1未支付,2支付成功,3支付失败,4处理中(支付过,但结果未知)
public void tixian2(OrderInfo orderInfo){
try {
OrderVO order = new OrderVO();
order.setAmount(orderInfo.getAmount());
order.setId(orderInfo.getId());
order.setName(orderInfo.getName());
//调用远程接口,从用户账号扣款,转账到自己账户
BankResponse response = bankService.moneyOut(order);
//根据远程接口返回的状态,判断是否支付成功
if(response !=null){//有返回值
if(response.getCode().equalsIgnoreCase("s")){
orderInfo.setStatus(2);
}else{
orderInfo.setStatus(3);
}
}else {//无返回值,这里这么写,代指超时或者网络异常等,不一定支付失败,实际情况要根据接口api来写这个判断
orderInfo.setStatus(4);
}
//保存订单状态,(编程式事务)
template.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus transactionStatus) {
orderInfoDao.updateByPrimaryKey(orderInfo);
return null;
}
});
}catch (Exception e){
e.printStackTrace();
}
}
该代码避免了第一种写法的两个问题,貌似完美但仍有一个问题,如果由于某种原因,比如用户点击了两次,或者该订单是通过mq发过来的,而mq有可能重发消息,这样的话就会导致同一个用户多次支付,如何避免?
3、第三种写法
public void tixian3(OrderInfo orderInfo){
try {
int rows = orderInfoDao.update("update order_info set status=4 where order_info_id=? and status=1",new Object[]{orderInfo.getId()});
if(rows == 1){
OrderVO order = new OrderVO();
order.setAmount(orderInfo.getAmount());
order.setId(orderInfo.getId());
order.setName(orderInfo.getName());
//调用远程接口,从用户账号扣款,转账到自己账户
BankResponse response = bankService.moneyOut(order);
//根据远程接口返回的状态,判断是否支付成功
if(response !=null){//有返回值
if(response.getCode().equalsIgnoreCase("s")){
orderInfo.setStatus(2);
}else{
orderInfo.setStatus(3);
}
}else {//无返回值,不一定支付失败,可能是超时或者网络异常等
orderInfo.setStatus(4);
}
//保存订单状态,(编程式事务)
template.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus transactionStatus) {
orderInfoDao.updateByPrimaryKey(orderInfo);
return null;
}
});
}
}catch (Exception e){
e.printStackTrace();
}
}
跟2的区别是开始的时候修改了状态,使得后续的相同订单处理无效。这是一种乐观锁的处理方式,这样就避免了2中所说的多次支付问题。
远程调用历史及代码编写demo的更多相关文章
- 轻量级远程调用框架-Hessian学习笔记-Demo实现
Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...
- dotNET使用DRPC远程调用运行在Storm上的Topology
Distributed RPC(DRPC)是Storm构建在Thrift协议上的RPC的实现,DRPC使得你可以通过多种语言远程的使用Storm集群的计算能力.DRPC并非Storm的基础特性,但它确 ...
- SpringCloud使用Nacos服务发现实现远程调用
本文使用SpringCloud结合Nacos服务发现,Feign远程调用做一个简单的Demo. 1 Nacos 关于Nacos之前写了两篇文章关于SpringBoot对它的使用,感兴趣可以查看一下. ...
- 2019.12.4 Hystix熔断&Feign进行远程调用&Zuul
0.学习目标 会配置Hystix熔断 会使用Feign进行远程调用 能独立搭建Zuul网关 能编写Zuul的过滤器 1.Hystrix 1.1.简介 Hystrix,英文意思是豪猪,全身是刺,看起来就 ...
- [转载] 基于Dubbo的Hessian协议实现远程调用
转载自http://shiyanjun.cn/archives/349.html Dubbo基于Hessian实现了自己Hessian协议,可以直接通过配置的Dubbo内置的其他协议,在服务消费方进行 ...
- 基于Dubbo的Hessian协议实现远程调用
Dubbo基于Hessian实现了自己Hessian协议,可以直接通过配置的Dubbo内置的其他协议,在服务消费方进行远程调用,也就是说,服务调用方需要使用Java语言来基于Dubbo调用提供方服务, ...
- Dubbo搭建HelloWorld-搭建服务提供者与服务消费者并完成远程调用(附代码下载)
场景 Dubbo简介与基本概念: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103555224 Dubbo环境搭建-ZooKe ...
- 【lombok】使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法
错误如题:使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法 报错如下: 解决方法: 1.首先查看你的lombok插件是否下载安 ...
- ZooKeeper伪分布集群安装及使用 RMI+ZooKeeper实现远程调用框架
使用 RMI + ZooKeeper 实现远程调用框架,包括ZooKeeper伪集群安装和代码实现两部分. 一.ZooKeeper伪集群安装: 1>获取ZooKeeper安装包 下载地址:ht ...
随机推荐
- linux文件链接
我的github,欢迎关注,分享知识与技术 链接:一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法. Linux中包括两种链接:硬链接(HardLink)和软链接(Soft Link), ...
- 洛谷P3674 小清新人渣的本愿(莫队)
传送门 由乃tql…… 然后抄了一波zcy大佬的题解 我们考虑把询问给离线,用莫队做 然后用bitset维护,每一位代表每一个数字是否存在,记为$now1$ 然后再记录一个$now1$的反串$now2 ...
- P2480 [SDOI2010]古代猪文 Lucas+CRT合并
\(\color{#0066ff}{ 题目描述 }\) 猪王国的文明源远流长,博大精深. iPig在大肥猪学校图书馆中查阅资料,得知远古时期猪文文字总个数为N.当然,一种语言如果字数很多,字典也相应会 ...
- luogu4240 毒瘤之神的考验(毒瘤乌斯反演)
link 题意:求出\(\sum_{i=1}^n\sum_{j=1}^m\varphi(ij)\),对998244353取模 多组数据,\(T\le 10^4,n,m\le 10^5\). 前置知识: ...
- peaks
给定一个无向图,点有点权边有边权 Q次询问,每次询问从点v开始只经过边权<=x的边能到达所有点中点权第k大值,无解输出-1 N<=1e5,M,Q<=5e5 建立大根kruskal重构 ...
- 牛客nowcoder NOIP普及组第三场
qtmd AK了 直接题解吧 题目链接 A-十七边形 牛牛想在一个半径为r的圆中,找到一个内接的十七边形,使他的面积最大.输入半径r,输出最大的面积. 1 <= r <= 10000 在1 ...
- 「产品经理全连接系列2」企业如何开展敏捷或DevOps的研发变革
大家好,我是华为云的产品经理 恒少: 作为布道师和产品经理,出差各地接触客户是常态,经常和华为云的客户交流.布道.技术沙龙,但是线下交流,覆盖的用户总还是少数. 我希望可以借线上的平台,和用户持续交流 ...
- [USACO5.4]奶牛的电信Telecowmunication 最小割
题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...
- 分析mybatis和jdbc的作用,已经原理
从jdbc的操作数据库来看:主要分为几步: 1 注冊载入JDBC驱动程序: 2 得到连接对象 Connection 3 创建 Statement对象 4 运行sql语句 5 处理结果 6 关闭资源释放 ...
- Django 09 博客小案例
Django 09 博客小案例 urls.py from django.urls import path from . import views urlpatterns = [ path('index ...