背景描述,一个商城网站,一个订单支付方案有多个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.同一个订单多个线程访问,一个个处理

2.多个订单多个线程,可以一起处理,完成的时间一样

3.同时运行

如有问题,请指出。

多线程demo,订单重复支付的更多相关文章

  1. 订单退款&重复支付需求疑问点归纳整理

    更新历史记录: 更新内容 更新人 更新时间 新建 Young 2020.12.10  16:45 更新产品疑问解答 Young 2020.12.11  10:14 更新退款权益终止时间 Young 2 ...

  2. 黄聪:微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付

    一.首先先确定H5支付权限已经申请! 二.开发流程 1.用户在商户侧完成下单,使用微信支付进行支付 2.由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB ...

  3. 微信支付id出现的重复支付解决方法和app应用中多种支付方式之间的对比

    1.微信支付的transId发起支付请求,未登录微信,先帐号登陆,否则直接去支付.这样的话,该transId跟该帐号绑定起来了, 如果下一次再重新使用该transId来支付请求,但是想切换其他的微信帐 ...

  4. WEB安全新玩法 [8] 阻止订单重复提交

    交易订单的重复提交虽然通常不会直接影响现金流和商品流,但依然会给网站运营方带来损害,如消耗系统资源.影响正常用户订单生成.制造恶意用户发起纠纷的机会等.倘若订单对象是虚拟商品,也有可能造成实际损失.订 ...

  5. Java 编程 订单、支付、退款、发货、退货等编号主动生成类

    订单.支付.退款.发货.退货等编号主动生成类 在商城网站中,订单编号的自动生成,ERP中各个单据的编号自动生成,都可以按照一下的方式来自动生成. 第一步:定义常量订单编号前缀.订单编号起始数.订单编号 ...

  6. 苹果应用内购 ios 开发者根据用户提供的邮件中的订单号查看该订单是否支付成功

    苹果应用内购 ios 开发者根据用户提供的邮件中的订单号查看该订单是否支付成功 这是苹果wwdc2021 推出的新功能 参考官网链接 App Store Server API | Apple Deve ...

  7. Java 实现订单未支付超时自动取消

    在电商上购买商品后,如果在下单而又没有支付的情况下,一般提示30分钟完成支付,否则订单自动.比如在京东下单为完成支付: 超过24小时,就会自动取消订单,下面使用 Java 定时器实现超时取消订单功能. ...

  8. 微信支付之01------获取订单微信支付二维码的接口------Java实现

    [ 前言:以前写过一个获取微信二维码支付的接口,发现最近公司新开的项目会经常用到,现在我又翻出代码看了一遍,觉得还是把整个代码流程记下来的好 ] 借鉴博客: 他这篇博客写得不错,挺全的:https:/ ...

  9. 微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付

    服务项目 新手技术咨询 企业技术咨询 定制开发 服务说明 QQ有问必答 QQ.微信.电话 微信开发.php开发,网站开发,系统定制,小程序开发 价格说明 200元/月 1000/月 商议       ...

随机推荐

  1. mongo学习链接

    http://www.runoob.com/mongodb/mongodb-create-database.html

  2. CentOS7.5安装MongoDB4.0与CRUD基本操作

    一 MongoDB简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数 ...

  3. Java与Redis

    1.下载Java使用Redis架包并引入 jedis-2.9.0.jar 2.用Java使用Redis如下: package com.jef.redis; import redis.clients.j ...

  4. 成功实施的APS项目故事分享---如何管理与激励APS项目团队

    故事背景 A企业是易普优APS重要客户之一,是某行业的龙头企业:APS项目历时7个月顺利上线,十个月验收!通过易普优APS的顺利实施,建成了集团的精益计划管控运营平台,树立计划的权威与指挥棒作用,让物 ...

  5. Ubuntu 17.04 搭建 NodeJS

    可以在云主机上执行以下的命令: apt-get update apt-get install -y python-software-properties software-properties-com ...

  6. Ruby windows7安装配置(最新版本)

    1.下载最新版本的rubyinstaller并安装http://rubyinstaller.org/downloads/ 如下图所示设置路径,我安装时将所有选项都打够了,免除了后面需要什么配置麻烦. ...

  7. api设计 - php 接口 token 数据加密

    最近在用php写app的接口,有一些疑问 首先关于token(令牌)token是用户登录的时候生成的 用户token在服务端保存入库 客户端则缓存在本地 大部分接口都要求客户端发送token 和服务端 ...

  8. chrome安装(sentos7)

    在服务器上安装chrome是用来模拟浏览器抓取数据的. 直接 yum install chrome是安装不了的 你要做以下几步就可以了. 配置yum源 1. vim /etc/yum.repos.d/ ...

  9. firewalld启动问题

    问题 在查看或启动firewalld服务时,提示"Warning: firewalld.service changed on disk. Run 'systemctl daemon-relo ...

  10. 使用DNSPod域名解析

    1 在GoDaddy域名注册商 注册域名 https://sg.godaddy.com/zh/ 2 登陆DNSPod https://www.dnspod.cn 3 选择域名解析 添加域名 4 添加记 ...