2013-02-16 37 views
5

Chúng tôi hiện đang đối mặt với một vấn đề với chèn đồng thời vào một trong các bảng máy chủ sal của chúng tôi từ nhiều máy khách. Tôi hy vọng các bạn có thể giúp chúng tôi.Máy chủ SQL - Chèn Đồng thời vào bảng từ nhiều máy khách - Kiểm tra Giới hạn và Chặn

Chúng tôi đang sử dụng quy trình được lưu trữ để thực hiện các giao dịch. Trong quy trình được lưu trữ đó, đối với mỗi giao dịch, chúng tôi tính tổng doanh số cho đến thời điểm này. Nếu tổng doanh thu nhỏ hơn giới hạn đã đặt, thì giao dịch sẽ được cho phép. Nếu không, giao dịch sẽ bị từ chối.

nó hoạt động tốt hầu hết các lần. Tuy nhiên, đôi khi nhiều khách hàng cố gắng thực hiện giao dịch một cách chính xác cùng một lúc, kiểm tra giới hạn không thành công vì cả hai giao dịch đều được thực hiện.

Các bạn có thể đề xuất cách chúng tôi có thể thực thi hiệu quả giới hạn mọi lúc không? Có cách nào tốt hơn để làm điều đó không?

Cảm ơn!

+1

Vui lòng cung cấp cấu trúc bảng và dữ liệu mẫu của bạn. Là hằng số giới hạn được thiết lập cho tất cả các giao dịch? –

+0

Là linh cảm, vấn đề có thể được giải quyết nếu bạn thực hiện quy trình được lưu trữ nhanh hơn rất nhiều. Với 100ms va chạm được lưu trữ thủ tục sẽ là cực kỳ hiếm. Nếu bạn đăng truy vấn và định nghĩa bảng, chúng tôi có thể đề xuất một chỉ mục giúp tính tổng số rất nhanh. – Andomar

+0

vui lòng tìm cấu trúc bảng. Trong số tiền này (cổ phần) cho mỗi lần đặt cược không được vượt quá 1000. Giới hạn 1000 này được lưu trữ trong một bảng khác. \t [SlipID] [bigint] SẮC (1,1) NOT NULL, \t [TillID] [int] NOT NULL, \t [Mã vạch] [varchar] (30) NOT NULL, \t [GamingDate] [ngày] KHÔNG NULL, \t [DrawID] [int] NOT NULL, \t [BetNumber] [tinyint] NOT NULL, \t [CurrencyID] [int] NOT NULL, \t [Stake] [thập phân] (9, 2) NOT NULL , \t \t [SlipTime] [datetime] NOT NULL, – sammy

Trả lời

5

Tôi không nghĩ rằng có thể thực hiện điều này một cách rõ ràng.

Nếu tất cả chèn được đảm bảo để đi qua các thủ tục lưu trữ và SaleValue không được cập nhật một lần chèn thì sau đây nên làm việc (tôi đã lên bảng và cột tên vì đây là những không được cung cấp trong câu hỏi ban đầu)

DECLARE @SumSaleValue MONEY 

BEGIN TRAN 

SELECT @SumSaleValue = SUM(SaleValue) 
FROM dbo.Orders WITH (UPDLOCK, HOLDLOCK) 
WHERE TransactionId = @TransactionId 

IF @SumSaleValue > 1000 
    BEGIN 
    RAISERROR('Cannot do insert as total would exceed order limit',16,1); 
    ROLLBACK; 
    RETURN; 
    END 

/*Code for INSERT goes here*/ 

COMMIT 

HOLDLOCK Cho ngữ nghĩa nối tiếp và khóa toàn bộ phạm vi phù hợp với TransactionIdUPDLOCK ngăn hai giao dịch đồng thời khóa cùng phạm vi, do đó giảm nguy cơ deadlocks.

Chỉ mục trên TransactionId,SaleValue sẽ là cách tốt nhất để hỗ trợ truy vấn này.

+1

+1 thông minh! Có lẽ một chút quá thông minh, vì nó làm tăng thanh cho bất kỳ ai chỉnh sửa mã. Có thể là một ý tưởng tốt để đóng giao dịch trước khi thủ tục trả về. – Andomar

+0

@Andomar - Cảm ơn. Quên đi! –

+0

Cảm ơn Martin! Nó đã giúp ... Tuy nhiên, chúng tôi đã đi vào để tạo ra bảng tóm tắt với tổng giá trị được cộng hoặc trừ cho mỗi giao dịch.Ngoài ra, bảng bán hàng là rất lớn và mỗi lần truy vấn bảng để tính tổng số tiền mất thời gian vì quá nhiều chèn và chỉ mục bị phân mảnh quá nhanh .. vì vậy, chúng tôi quyết định có bảng tóm tắt ... Cho đến nay, nó giúp ... Cảm ơn! – sammy

Các vấn đề liên quan