当两个用户访问同一个方法时,结果是共享的

When two users access the same method, the result is shared

当我网站的 2 个不同用户同时创建产品销售时,我遇到了这个问题。这应该向服务器生成 2 个不同的请求并打印 2 个不同的销售票。问题是,当服务器请求同时进来(或彼此非常接近)时,两个分支打印相同的票,而不是各自打印自己的票。

这是我的代码:

Branch          Total   CreatedAt               ProductSaleId
EBQ Centro Maya 35.00   2016-06-13 15:35:54.743 3263825d-bca3-4d18-bbca-3eebe4c3398a
EBQ PA Chetumal 30.00   2016-06-13 15:35:54.647 01f52d7d-5745-426b-a973-4a701a18b8e4

这些是数据库条目,2 个不同的分支机构分别在 15:35:54 进行了销售。

因此,一旦完成销售,PrintReceipt 方法将按如下方式调用:

HelperObjects.ThermalPOS58.PrinterController.PrintReceipt(new InvoiceReceipt()
            {
                Discount = discount,
                InvoiceNumber = "TEST",
                SubTotal = decimal.Parse(createProductSale.Total),
                Total = total,
                Change = createProductSale.Change ?? "0",
                ClientAmount = createProductSale.ClientAmount,
                InvoiceDateFormatted =
                    DateTime.UtcNow.ConvertUtcTimeToTimeZone("", User.Identity.GetUserId())
                        .ToString("dd/MM/yyyy HH:mm:ss"),
                BranchName = _unitOfWork.BranchRepository.GetById(branchId).Name,
                InvoiceItems = invoiceReceipts,
                PrinterName = _unitOfWork.BranchRepository.GetById(branchId).PrinterName,
                IsTpv = createProductSale.IsTpv
            });

PrintReceipt 方法如下所示:

private static InvoiceReceipt _mappedInvoice ;

    public static void PrintReceipt(InvoiceReceipt invoiceReceipt)
    {
        _mappedInvoice = invoiceReceipt;
        var printNodeIntegration = new PrintNodeIntegration();
        printNodeIntegration.Print(GetDocument(), invoiceReceipt.PrinterName);
    }

每个调用都将其自己的发票发送到 PrintReceipt 方法并且工作正常,除非同时进行销售。发生这种情况时,两个分支机构都在打印同一张收据。通常是第一个进来的。

有什么想法吗?

static 个成员在 进程 中共享。在 ASP.NET 中,应用程序池中的所有会话都使用相同的进程,因此它们都共享相同的 static 状态。

静态 Session 属性 按用户会话分隔数据,因此它是 更好 保存会话特定数据的地方:

Session["mappedInvoice"] = invoiceReceipt;

但不清楚您如何使用它来了解它是否需要存储在会话中。通常,您使用会话来保存需要跨请求保留的数据。

private static InvoiceReceipt _mappedInvoice ;
private readonly static Object _lockObject = new Object();

public static void PrintReceipt(InvoiceReceipt invoiceReceipt)
{
    Lock(_lockObject)
    {
        _mappedInvoice = invoiceReceipt;
        var printNodeIntegration = new PrintNodeIntegration();
        printNodeIntegration.Print(GetDocument(), invoiceReceipt.PrinterName);
    }
}

这可以防止在设置 _mappedInvoice 和调用 .Print 之间的调用重置 _mappedInvoice。后面的调用会等到当前调用释放锁。