मेरे पास अनुक्रमिक संख्याओं (चालान संख्या या छात्र आईडी) के साथ एक तालिका है।डेटाबेस के समवर्ती उपयोग - दो उपयोगकर्ताओं को एक ही मान प्राप्त करने से रोकना
किसी बिंदु पर, उपयोगकर्ता को पिछले नंबर का अनुरोध करने की आवश्यकता है (अगली संख्या की गणना करने के लिए)। एक बार उपयोगकर्ता वर्तमान नंबर जानता है, तो उन्हें अगले नंबर जेनरेट करने और तालिका में जोड़ने की आवश्यकता है।
मेरी चिंता यह है कि दो उपयोगकर्ता समवर्ती पहुंच के कारण दो समान संख्याओं को गलती से उत्पन्न करने में सक्षम होंगे।
मैंने संग्रहित प्रक्रियाओं के बारे में सुना है, और मुझे पता है कि यह एक समाधान हो सकता है। क्या समवर्ती मुद्दों से बचने के लिए यहां एक सर्वोत्तम अभ्यास है?
संपादित: यहाँ क्या मैं अब तक है:
USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_GetNextOrderNumber]
AS
BEGIN
BEGIN TRAN
DECLARE @recentYear INT
DECLARE @recentMonth INT
DECLARE @recentSequenceNum INT
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- get the most recent numbers
SELECT @recentYear = Year, @recentMonth = Month, @recentSequenceNum = OrderSequenceNumber
FROM dbo.OrderNumbers
WITH (XLOCK)
WHERE Id = (SELECT MAX(Id) FROM dbo.OrderNumbers)
// increment the numbers
IF (YEAR(getDate()) > IsNull(@recentYear,0))
BEGIN
SET @recentYear = YEAR(getDate());
SET @recentMonth = MONTH(getDate());
SET @recentSequenceNum = 0;
END
ELSE
BEGIN
IF (MONTH(getDate()) > IsNull(@recentMonth,0))
BEGIN
SET @recentMonth = MONTH(getDate());
SET @recentSequenceNum = 0;
END
ELSE
SET @recentSequenceNum = @recentSequenceNum + 1;
END
-- insert the new numbers as a new record
INSERT INTO dbo.OrderNumbers(Year, Month, OrderSequenceNumber)
VALUES (@recentYear, @recentMonth, @recentSequenceNum)
COMMIT TRAN
END
यह काम करने के लिए लगता है, और मुझे मूल्यों मैं चाहता हूँ देता है। अभी तक, मैंने समवर्ती पहुंच को रोकने के लिए अभी तक कोई लॉकिंग नहीं जोड़ा है।
संपादित करें 2: लेनदेन पूरा होने तक तालिका को लॉक करने के लिए WITH(XLOCK)
जोड़ा गया। मैं यहां प्रदर्शन के लिए नहीं जा रहा हूं। जब तक मुझे डुप्लिकेट प्रविष्टियां नहीं मिलतीं, और डेडलॉक्स नहीं होते हैं, तो यह काम करना चाहिए।
जो संख्या मैं उत्पन्न करूँगा वह वर्ष (3 अंक), महीने (2 अंक) के बाद, उसके बाद 3 अंकों की संख्या होती है जो हर महीने शून्य पर रीसेट हो जाती है। तो 012 03 000 की तरह कुछ। –
इस बात पर निर्भर करता है कि वह 3 अंकों का नंबर कहां से आ रहा है, आप आसानी से गणना किए गए कॉलम के साथ इसे हल कर सकते हैं। अन्यथा, एक प्रक्रिया – Diego
का उपयोग करें 3 अंकों की संख्या केवल पिछले संख्या से बढ़ी है (जब तक कि पिछले नंबर पिछले महीने से नहीं है, तब संख्या 0 फिर से है) –