多线程demo,订单重复支付
背景描述,一个商城网站,一个订单支付方案有多个1.金额支付2.积分支付3.工资支付(分期和全额),所以一个订单的方案可能有1;有1、2,或1、2、3
状态,1.订单状态,2,支付状态==>多方案的订单有多个支付状态。
问题发现,一个订单多次支付!!!
于是分析,找解决方案。
1.DB 行锁
2.多线程控制
多线程测试参考 链接
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleThread
{
class Program
{
const string firstOrderId = "";
const string secondOrderId = "";
const string thirdOrderId = "";
static void Main(string[] args)
{
test(LockType.LockObject);
test(LockType.LockStaticObject);
test(LockType.LockString);
test(LockType.LockThis);
}
static void test(LockType lockType)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("----------------测试相同的订单-------------------");
Console.ForegroundColor = ConsoleColor.Green;
OrderPay(firstOrderId, , lockType);
OrderPay(firstOrderId, , lockType);
OrderPay(firstOrderId, , lockType); Thread.Sleep(); Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("----------------测试不同的订单-------------------");
Console.ForegroundColor = ConsoleColor.Green;
OrderPay(firstOrderId, , lockType);
OrderPay(secondOrderId, , lockType);
OrderPay(thirdOrderId, , lockType); } static void OrderPay(string orderId, int threadNo, LockType lockType)
{
new Thread(() => new Payment(orderId, threadNo).Pay(lockType)).Start();
Thread.Sleep();
}
} public class Payment
{
private readonly string LockString;
private readonly int ThreadNo;
private readonly Object LockObj = new object();
private static readonly Object StaticLockObj = new object(); public Payment(string orderId, int threadNo)
{
this.LockString = orderId;
this.ThreadNo = threadNo;
} public void Pay(LockType lockType)
{
ShowMessage("等待资源");
switch (lockType)
{
case LockType.LockThis:
lock (this)
{
ShowAction();
}
break;
case LockType.LockString:
lock (LockString)
{
ShowAction();
}
break;
case LockType.LockObject:
lock (LockObj)
{
ShowAction();
}
break;
case LockType.LockStaticObject:
lock (StaticLockObj)
{
ShowAction();
}
break;
default:
break;
}
ShowMessage("释放资源");
}
private void ShowAction()
{
ShowMessage("进入锁并开始操作");
Thread.Sleep();
ShowMessage("完成操作,时间" + DateTime.Now);
}
private void ShowMessage(string message)
{
Console.WriteLine(string.Format("订单{0}的第{1}个线程{2}", LockString, ThreadNo, message));
}
}
public enum LockType
{
LockThis = ,
LockString = ,
LockObject = ,
LockStaticObject =
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleThread2
{
class Program
{
/// <summary>
/// 订单号
/// </summary>
const string firstOrderId = "d001";
const string secondOrderId = "d002";
const string thirdOrderId = "d003";
const string fourthOrderId = "d004";
const string fivthOrderId = "d005";
static void Main(string[] args)
{
Test();
}
static void Test()
{
ConsoleOut.WriteWhite("----------------测试-------------------");
//相同的订单 一个一个来
OrderPay(firstOrderId, );
OrderPay(firstOrderId, );
OrderPay(firstOrderId, );
OrderPay(firstOrderId, );
//不同的订单可以同时处理
OrderPay(secondOrderId, );
OrderPay(thirdOrderId, );
OrderPay(fourthOrderId, );
OrderPay(fivthOrderId, );
}
/// <summary>
/// 多线程支付
/// </summary>
/// <param name="orderId">订单号</param>
/// <param name="threadNo">线程编号</param>
static void OrderPay(string orderId, int threadNo)
{
new Thread((object x) => Payment.Pay(new object[] { orderId, threadNo })).Start();
}
}
/// <summary>
/// 锁字典一个订单对映一个锁
/// </summary>
public static class DicLockManage
{
/// <summary>
/// 根据订单id得到,锁资源
/// </summary>
public static Dictionary<string, object> dicLock = new Dictionary<string, object>();
/// <summary>
/// 字典操作的锁
/// </summary>
public static readonly object objLock = new object();
/// <summary>
/// 得到订单锁
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static object GetKeyValue(string key)
{
lock (objLock)
{
if (dicLock.ContainsKey(key))
{
return dicLock[key];
}
else
{
dicLock.Add(key, new object());
return GetKeyValue(key);
}
}
}
}
/// <summary>
/// 订单支付类
/// </summary>
public static class Payment
{
/// <summary>
/// 模拟支付方法
/// </summary>
/// <param name="objParams"></param>
public static void Pay(object[] objParams)
{
object[] Params = objParams as object[];
string OrderId = Params[].ToString();
int ThreadNo = Convert.ToInt32(Params[]);
//加锁
lock (DicLockManage.GetKeyValue(OrderId))
{
ShowMessage(OrderId, ThreadNo, "等待资源");
ShowAction(OrderId, ThreadNo);//模拟支付
ShowMessage(OrderId, ThreadNo, "释放锁");
}
}
private static void ShowAction(string OrderId, int ThreadNo)
{
ShowMessage(OrderId, ThreadNo, "进入锁并开始操作");
ConsoleOut.WriteRed("线程" + ThreadNo + "处理中...");
Thread.Sleep();
ConsoleOut.WriteGreen("线程" + ThreadNo + "完成处理...");
ShowMessage(OrderId, ThreadNo, "完成操作,时间" + DateTime.Now);
}
private static void ShowMessage(string OrderId, int ThreadNo, string message)
{
ConsoleOut.WriteYellow(string.Format("订单{0}的第{1}个线程{2}", OrderId, ThreadNo, message));
}
}
/// <summary>
/// 输出类,设置颜色
/// </summary>
public static class ConsoleOut
{
public static void WriteWhite(string message)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(message);
}
public static void WriteRed(string message)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(message);
}
public static void WriteYellow(string message)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(message);
}
public static void WriteGreen(string message)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(message);
}
}
}
测试图
1.同一个订单多个线程访问,一个个处理

6W}T3YE(FK3A}$[L.jpg)
2.多个订单多个线程,可以一起处理,完成的时间一样

3.同时运行

如有问题,请指出。
多线程demo,订单重复支付的更多相关文章
- 订单退款&重复支付需求疑问点归纳整理
		更新历史记录: 更新内容 更新人 更新时间 新建 Young 2020.12.10 16:45 更新产品疑问解答 Young 2020.12.11 10:14 更新退款权益终止时间 Young 2 ... 
- 黄聪:微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付
		一.首先先确定H5支付权限已经申请! 二.开发流程 1.用户在商户侧完成下单,使用微信支付进行支付 2.由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB ... 
- 微信支付id出现的重复支付解决方法和app应用中多种支付方式之间的对比
		1.微信支付的transId发起支付请求,未登录微信,先帐号登陆,否则直接去支付.这样的话,该transId跟该帐号绑定起来了, 如果下一次再重新使用该transId来支付请求,但是想切换其他的微信帐 ... 
- WEB安全新玩法 [8] 阻止订单重复提交
		交易订单的重复提交虽然通常不会直接影响现金流和商品流,但依然会给网站运营方带来损害,如消耗系统资源.影响正常用户订单生成.制造恶意用户发起纠纷的机会等.倘若订单对象是虚拟商品,也有可能造成实际损失.订 ... 
- Java 编程 订单、支付、退款、发货、退货等编号主动生成类
		订单.支付.退款.发货.退货等编号主动生成类 在商城网站中,订单编号的自动生成,ERP中各个单据的编号自动生成,都可以按照一下的方式来自动生成. 第一步:定义常量订单编号前缀.订单编号起始数.订单编号 ... 
- 苹果应用内购 ios 开发者根据用户提供的邮件中的订单号查看该订单是否支付成功
		苹果应用内购 ios 开发者根据用户提供的邮件中的订单号查看该订单是否支付成功 这是苹果wwdc2021 推出的新功能 参考官网链接 App Store Server API | Apple Deve ... 
- Java 实现订单未支付超时自动取消
		在电商上购买商品后,如果在下单而又没有支付的情况下,一般提示30分钟完成支付,否则订单自动.比如在京东下单为完成支付: 超过24小时,就会自动取消订单,下面使用 Java 定时器实现超时取消订单功能. ... 
- 微信支付之01------获取订单微信支付二维码的接口------Java实现
		[ 前言:以前写过一个获取微信二维码支付的接口,发现最近公司新开的项目会经常用到,现在我又翻出代码看了一遍,觉得还是把整个代码流程记下来的好 ] 借鉴博客: 他这篇博客写得不错,挺全的:https:/ ... 
- 微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付
		服务项目 新手技术咨询 企业技术咨询 定制开发 服务说明 QQ有问必答 QQ.微信.电话 微信开发.php开发,网站开发,系统定制,小程序开发 价格说明 200元/月 1000/月 商议 ... 
随机推荐
- day4作业模拟实现一个ATM + 购物商城程序
			作业需求: 模拟实现一个ATM + 购物商城程序 1.额度 15000或自定义: 2.实现购物商城,买东西加入 购物车,调用信用卡接口结账: 3.可以提现,手续费5%: 4.每月22号出账单,每月10 ... 
- 【LOJ】#2035. 「SDOI2016」征途
			题解 有人管它叫带权二分,有人管它叫dp凸优化,有人管它叫wqs二分-- 延伸出来还有zgl分治,xjp¥!%#!@#¥!# 当我没说 我们拆个式子,很容易发现所求的就是 \(m\sum_{i = 1 ... 
- http://localhost/ 或 http://127.0.0.1/ 报错:HTTP 404 的解决办法
			一些初次接触使用 Eclipse 工具来开发 JAVA Web 工程的开发人员,可能会对 Eclipse 和 Tomcat 的绑定产生一个疑惑. 那就是 在修改了 Tomcat 的8080端口为80后 ... 
- pandas实战——对星巴克数据的分析
			一.实验对象 实验对象为星巴克在全球的门店数据,我们可以使用pandas对其进行简单的分析,如分析每个国家星巴克的数量,根据门店数量对国家进行排序等. 二.数据分析 1.读取数据并获取数据行列数 首先 ... 
- 02:实现Singleton模式
			Java实现单例模式有很多种实现方法,其中我们应根据需要选择线程安全的与非线程安全的两种方式,根据对象实现的方式又分为饱汉与饿汉方式. 这里使用java中的volatile关键字与synchroniz ... 
- ThinPHP3.2中 addAll()批量插入数据
			thinkphp中model类的addAll()方法可以将数据同时添加到数据库中. 1 2 3 4 5 6 // 批量添加数据 (only MySQL) $user = M('user'); //ar ... 
- 在LINUX环境下定时执行php脚本
			1. 使用Crontab定时执行linux环境下的php脚本文件 Cron,它是一个linux下的定时执行工具.根用户以外的用户可以使用 crontab 工具来配置 cron 任务.所有用户定义的 c ... 
- CSS 显示或隐藏子元素
			很多时候我们仅仅只是想让鼠标移动入某个元素,然后显示出某个元素. 大多数博客的标题或内容都是:使用CSS实现鼠标悬停在一行上,显示某些元素 很遗憾,这是错误的,鼠标悬停后,尽管CSS标准中有定义此种方 ... 
- 绝对良心的 Java 中发邮件功能
			开篇语,是不是感觉这个功能都老掉牙了,网上一大推的文章,随便找个代码就是了,为什么我还要选择专门写一篇呢,因为我遇到了不一样的坑…… 首先,不免俗套的把代码都贴上来,拿去执行吧,记住换上你的账号和授权 ... 
- BoneBlack am335x can0 通讯配置与测试
			准备工具: 1.内核3.14.65,u-boot.文件系统 2.boneblack开发板 3.串口线.电源线,测试线,测试夹 一.配置内核支持CAN通讯 [*] Networking support ... 
