2008-11-17 24 views
14

के रूप में एक डीबी तालिका का उपयोग करने का सबसे अच्छा तरीका मेरे पास ~ 50K पंक्तियों के साथ एक डेटाबेस तालिका है, प्रत्येक पंक्ति एक नौकरी का प्रतिनिधित्व करती है जिसे करने की आवश्यकता है। मेरे पास एक ऐसा प्रोग्राम है जो डीबी से नौकरी निकालता है, नौकरी करता है और परिणाम को वापस डीबी में डाल देता है। (यह प्रणाली अभी चल रही है)संदेश/नौकरी कतार

अब मैं एक से अधिक प्रसंस्करण कार्य को नौकरियों को करने की अनुमति देना चाहता हूं लेकिन यह सुनिश्चित कर लें कि कोई कार्य दो बार नहीं किया जाता है (प्रदर्शन चिंता के रूप में यह अन्य समस्याओं का कारण नहीं बनता है)। क्योंकि पहुँच एक sproce के रास्ते, मेरे वर्तमान से है, हालांकि इस

update tbl set owner=connection_id() where avalable and owner is null limit 1; 
select stuff from tbl where owner = connection_id(); 

BTW तरह दिखता है कि कुछ के साथ sproce कहा की जगह; कार्यकर्ता के कार्य नौकरी पाने और परिणामों को सबमिट करने के बीच कनेक्शन छोड़ सकते हैं। इसके अलावा, मुझे उम्मीद नहीं है कि डीबी बोतल की गर्दन होने के करीब भी आ जाए, जब तक कि मैं उस भाग को गड़बड़ न करूं (~ 5 नौकरियां प्रति मिनट)

क्या इसमें कोई समस्या है? क्या ऐसा करने के लिए इससे अच्छा तरीका है?

नोट: "Database as an IPC anti-pattern" केवल थोड़ी अप्रिय है क्योंकि 1) मैं आईपीसी नहीं कर रहा हूं (पंक्तियों को उत्पन्न करने की कोई प्रक्रिया नहीं है, वे सभी अभी पहले से मौजूद हैं) और 2) उस विरोधी पैटर्न के लिए वर्णित प्राथमिक पकड़ यह है कि यह डीबी पर अनियंत्रित लोड के परिणामस्वरूप होता है क्योंकि प्रक्रियाओं के लिए संदेश इंतजार करते हैं (मेरे मामले में, यदि कोई संदेश नहीं है, सबकुछ बंद हो जाता है क्योंकि सबकुछ बंद हो जाता है)

+0

सही-खराब = सिंक्रोनस आईपीसी एक डीबीएमएस पर अवरुद्ध करने के साथ पढ़ने के रूप में चुनें। आप संभवतः एसिंक्रोनिटी को पेश करने की रणनीति के रूप में ऐसा कर रहे हैं। – dkretz

+0

बीटीडब्ल्यू, यदि आप एक टाइमर पर पाठक रखना चाहते हैं, तो उन्हें बार-बार जांचना उपयोगी होता है, लेकिन अगर उन्हें काम मिल जाता है, तो वे फिर से सोने से पहले कतार को निकाल सकते हैं। – dkretz

+0

मेरा संपादन नोट करें: यदि उन्हें कोई काम नहीं मिलता है, तो उन्हें कभी भी काम नहीं मिलेगा। लेकिन अगर यह सच नहीं था ... – BCS

उत्तर

12

यहाँ क्या मैं अतीत में सफलतापूर्वक उपयोग किया है:

MsgQueue तालिका स्कीमा

MsgId identity -- NOT NULL 
MsgTypeCode varchar(20) -- NOT NULL 
SourceCode varchar(20) -- process inserting the message -- NULLable 
State char(1) -- 'N'ew if queued, 'A'(ctive) if processing, 'C'ompleted, default 'N' -- NOT NULL 
CreateTime datetime -- default GETDATE() -- NOT NULL 
Msg varchar(255) -- NULLable 

आपका संदेश प्रकार कर रहे हैं कि तुम क्या उम्मीद थी - संदेश जो प्रक्रिया (एस) डालने और प्रक्रिया (एस) पढ़ने, एक्सएमएल के साथ संरचित या प्रतिनिधित्व की आपकी अन्य पसंद के बीच अनुबंध के अनुरूप होते हैं (उदाहरण के लिए जेएसओएन कुछ मामलों में आसान होगा)।

फिर 0-टू-एन प्रक्रियाएं डाली जा सकती हैं, और 0-से-एन प्रक्रियाएं संदेशों को पढ़ और संसाधित कर सकती हैं, प्रत्येक पढ़ने की प्रक्रिया आम तौर पर एक संदेश प्रकार को संभालती है। लोड-बैलेंसिंग के लिए प्रक्रिया प्रकार के कई उदाहरण चल सकते हैं।

पाठक एक संदेश खींचता है और राज्य को "ए" ctive में बदलता है जबकि यह उस पर काम करता है। जब यह किया जाता है तो यह राज्य को "सी" में बदल देता है। यह संदेश को हटा सकता है या नहीं कि आप ऑडिट ट्रेल रखना चाहते हैं या नहीं। राज्य = 'एन' के संदेश MsgType/Timestamp ऑर्डर में खींचे जाते हैं, इसलिए MsgType + State + CreateTime पर एक अनुक्रमणिका है।

विविधताएं:
"ई" रोटर के लिए राज्य।
रीडर प्रक्रिया कोड के लिए कॉलम। राज्य संक्रमण के लिए
टाइमस्टैम्प।

इसने कई चीजों को करने के लिए एक अच्छा, स्केलेबल, दृश्यमान, सरल तंत्र प्रदान किया है जैसा कि आप वर्णन कर रहे हैं। यदि आपके पास डेटाबेस की बुनियादी समझ है, तो यह बहुत मूर्ख और एक्स्टेंसिबल है।टिप्पणियों से


कोड:

CREATE PROCEDURE GetMessage @MsgType VARCHAR(8)) 
AS 
DECLARE @MsgId INT 

BEGIN TRAN 

SELECT TOP 1 @MsgId = MsgId 
FROM MsgQueue 
WHERE MessageType = @pMessageType AND State = 'N' 
ORDER BY CreateTime 


IF @MsgId IS NOT NULL 
BEGIN 

UPDATE MsgQueue 
SET State = 'A' 
WHERE MsgId = @MsgId 

SELECT MsgId, Msg 
FROM MsgQueue 
WHERE MsgId = @MsgId 
END 
ELSE 
BEGIN 
SELECT MsgId = NULL, Msg = NULL 
END 

COMMIT TRAN 
+0

"पाठक एक संदेश खींचता है और राज्य को" ए "ctive में बदलता है, जबकि यह वर्णन करता है।" वह हिस्सा है जिसमें मुझे रूचि है। आप यह कैसे करते हैं? (इसके अलावा, ऐसा लगता है कि मेरा सामान आपके सामान के लिए आवश्यक सामानों के समान ही है।) – BCS

+0

ठीक है, जिसके लिए BEGIN TRAN और COMMIT TRAN के बीच कई SQL कथन की आवश्यकता है। तत्काल अनुसरण - अगले संदेश को खींचने के लिए एक एसपी - थोड़ा सा हैक किया गया है, मैंने पूर्व-ट्रे/कैच लिखा था क्योंकि मैंने त्रुटि फँस दी है। – dkretz

+1

- भाग 1 बनाएं प्रक्रिया GetMessage @MsgType VARCHAR (8) ) के रूप में घोषणा @MsgId INT TRAN शुरू चयन टॉप 1 @MsgId = msgId से MsgQueue कहां MessageType = @pMessageType और राज्य = 'एन' द्वारा आदेश CreateTime – dkretz

-1

आप "आईपीसी के रूप में डेटाबेस" एंटीपाटरन को लागू करने की कोशिश कर रहे हैं । यह समझने के लिए इसे देखें कि आपको अपने सॉफ़्टवेयर को फिर से डिज़ाइन करने पर विचार क्यों करना चाहिए।

+1

आप कैसे जानते हैं कि यह इस मामले में एक एंटीपाटर है, या सॉफ्टवेयर डिजाइन अनुचित है? आपके पास इस टिप्पणी को आधार देने के लिए कोई संदर्भ नहीं है। –

+0

एक त्वरित Google को "आईपीसी के रूप में डेटाबेस" पर कुछ भी नहीं मिला है –

+0

मैं इसे एसिंक्रोनस आईपीसी के लिए एक उपयोगी पैटर्न कहूंगा। आप किसी भी बगीचे-विविध संदेश कतार की तरह काम करने के लिए इसे कॉन्फ़िगर कर सकते हैं, और वे मेरे अनुभव ब्रांडेड "एंटीपाटरर्न" में नहीं हैं। – dkretz

0

स्वामी के स्वामित्व वाले होने के बजाय मालिक = शून्य होने के बजाय, आपको इसे नकली किसी भी रिकॉर्ड के बजाय सेट नहीं करना चाहिए। शून्य के लिए खोज इंडेक्स को सीमित नहीं करता है, आप टेबल स्कैन के साथ समाप्त हो सकते हैं। (इस ओरेकल के लिए है, एसक्यूएल सर्वर अलग हो सकता है)

1

बस एक संभव प्रौद्योगिकी परिवर्तन के रूप में, आप MSMQ या कुछ इसी तरह के उपयोग पर विचार हो सकता है।

आपकी प्रत्येक नौकरी/थ्रेड मैसेजिंग कतार से पूछताछ कर सकती है कि यह देखने के लिए कि कोई नया काम उपलब्ध है या नहीं। क्योंकि एक संदेश पढ़ने का कार्य इसे ढेर से हटा देता है, आपको यह सुनिश्चित किया जाता है कि केवल एक नौकरी/धागा संदेश प्राप्त होगा।

बेशक, यह माना जा रहा है कि आप एक माइक्रोसॉफ्ट मंच के साथ काम कर रहे हैं।

+0

मेरे पास डीबी में डेटा है, जब मैं कर रहा हूं तो मुझे डीबी में डेटा चाहिए। मेरे मामले में मुझे सिस्टम में एक और घटक जोड़ने का कोई कारण नहीं दिखता है। (बीटीडब्ल्यू http://www.microsoft.com/windowsserver2003/technologies/msmq/default.mspx) – BCS