2016-06-13 4 views
0

내 웹 사이트의 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 

이이 DB 항목이며, 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 방법으로 자신의 청구서를 보내는 판매가 동시에 이루어지는 경우를 제외하고는 잘 작동합니다. 이 경우 두 지점에서 동일한 영수증을 인쇄합니다. 일반적으로 처음에 온 것입니다.

아이디어가 있으십니까?

+4

'static '회원은 모든 세션에서 공유됩니다. 'Session'을 사용하거나 다른 방법으로 인보이스를 상태로 유지하십시오. –

+3

다른 곳에서'_mappedInvoice'를 사용하고 있습니까? 왜 정적 멤버가 필요합니까? –

+0

정적은 의심 스럽지만, GetDocument()에서 사용하지 않는 한 제공된 코드에서 이에 영향을 주어서는 안됩니다 (여기서 큰 붉은 깃발, 나는 의심 스럽다); 그래서 GetDocument()는 실제로 무엇을 하는가? GetDocument()에 대한 코드를 보여줍니다. GetDocument()에서 정적 변수 _mappedInvoice를 사용하는 경우 GetDocument()에 invoiceReceipt를 전달하는 대신 정적 변수를 사용하는 이유는 무엇입니까? –

답변

4

static 구성원은 프로세스 내에서 공유됩니다.. ASP.NET에서 응용 프로그램 풀의 모든 세션은 동일한 프로세스를 사용하므로 모두 동일한 static 상태를 공유합니다.

정적 Session 속성은 사용자 세션 데이터를 분리, 그래서 세션 별 데이터를 보유하는 더 나은 장소 :

Session["mappedInvoice"] = invoiceReceipt; 

그러나 당신이 그것을 사용하고 어떻게 그것을 경우도 알고 불분명 세션에 저장해야합니다. 일반적으로 요청을 통해 지속되어야하는 데이터를 보유하려면 세션을 사용합니다.

+0

네가 맞아, 세션에 저장된 정보는 실제로는 하나의 요청이므로 필요하지 않다. 가장 중요한 것은 동일한 상태를 공유하는 것이 내가하려는 일과 정확히 반대되는 것처럼 들리는 것입니다. 그것이 정적이 아닌 것처럼 보이게 내 문제를 해결할 것 같습니다. – Benjamin

-1
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을 다시 호출 할 때 사이에 와서 전화를 방지 할 수 있습니다. 이후 호출은 현재 호출이 잠금을 해제 할 때까지 대기합니다.

+2

이렇게하면 병렬로 실행하지 않을 이유가 없어도 이러한 작업이 병렬로 실행되는 것을 불필요하게 막을 수 있습니다. – Servy

+0

여기에 정적 방법을 사용하는 구체적인 이유가있을 수 있습니다. 질문은 별도로 언급하지 않았습니다. 그렇다면이 대답은 코드가 왜 동작하는지 설명하고이를 수정하는 방법을 설명합니다. 당신은 원래의 질문에 언급 된 정보로부터 이것이 사실이 아니라는 것을 알 수있는 방법이 없습니다. 당신은 그가 정적 방법이 필요 없다는 가정을했습니다. 정적 인 사용에 대한 특별한 이유가 없다고 가정 할 때 모든 것이 평등하고 병렬 실행이 더 좋을 것이라는 것에 동의합니다. – Kevin

+0

질문은 문제의 데이터가 사실 특정 요청임을 분명하게 나타내 었으며 심지어 각 요청에 대한 예제 데이터를 보여주었습니다. 이 데이터를 공유해서는 안된다는 가정은 아닙니다. 정보가 공유되지 않는 것이 명시된 요구 사항의 일부입니다. – Servy