उपयोगकर्ता इंटरफ़ेस में डीबी बाधा उल्लंघन को कैसे संभालें?


12

हम संग्रहीत प्रोसेस का उपयोग करते हुए डेटाबेस में हमारे अधिकांश व्यावसायिक नियमों को लागू करते हैं।

मैं कभी भी तय नहीं कर सकता कि डाटाबेस से उपयोगकर्ता इंटरफ़ेस में डेटा बाधा उल्लंघन त्रुटियों को कैसे पारित किया जाए। जिन बाधाओं के बारे में मैं बात कर रहा हूं वे डेटा अखंडता की तुलना में व्यवसाय नियमों के लिए अधिक बंधे हैं।

उदाहरण के लिए, "डुप्लिकेट कुंजी पंक्ति सम्मिलित नहीं कर सकता" जैसी एक डीबी त्रुटि व्यवसाय नियम के समान है "आपके पास एक ही नाम से एक से अधिक Foo नहीं हो सकते हैं"। लेकिन हमने इसे सबसे सामान्य ज्ञान स्थान पर "कार्यान्वित" किया है: एक अद्वितीय बाधा के रूप में जो नियम का उल्लंघन होने पर अपवाद फेंकता है।

अन्य नियम जैसे कि "आपको केवल 100 Foos प्रतिदिन की अनुमति है" त्रुटियों का कारण नहीं बनता है, क्योंकि उन्हें return empty dataset जैसे कस्टम कोड द्वारा सुन्दर तरीके से संभाला जाता है, जो कि एप्लिकेशन कोड जांचता है और वापस भेजता है यूई परत।

और इसमें रगड़ है। हमारे ui कोड इस तरह दिखता है (इस AJAX.NET webservices कोड है, लेकिन किसी भी ajax ढांचे करना होगा):

WebService.AddFoo("foo", onComplete, onError); // ajax call to web service 

function onComplete(newFooId) { 
    if(!newFooId) { 
     alert('You reached your max number of Foos for the day') 
     return 
    } 
    // update ui as normal here 
} 

function onError(e) { 
    if(e.get_message().indexOf('duplicate key')) { 
     alert('A Foo with that name already exists'); 
     return; 
    } 
    // REAL error handling code here 
} 

(एक पक्ष नोट के रूप में: मैं नोटिस इस जब आप टिप्पणी बहुत जल्दी प्रस्तुत stackoverflow क्या करता है: सर्वर HTTP 500 प्रतिक्रिया उत्पन्न करता है और ui इसे पकड़ता है।)

तो आप देखते हैं कि हम यहां दो स्थानों पर व्यवसाय नियम उल्लंघन का संचालन कर रहे हैं, जिनमें से एक (यानी अद्वितीय कॉन्स्टेंट त्रुटि) को एक विशेष मामले के रूप में संभाला जा रहा है कोड वास्तविक त्रुटियों (व्यवसाय नियम उल्लंघन नहीं) को संभालने वाला माना जाता है, क्योंकि .NET onError() हैंडलर तक सभी तरह से अपवादों का प्रचार करता है।

यह गलत लगता है। मेरे विकल्प मुझे लगता है कि कर रहे हैं:

  1. पकड़ 'नकली चाबी उल्लंघन की ऐप्लिकेशन सर्वर के स्तर पर अपवाद और कन्वर्ट यह जो कुछ भी करने के लिए यह ui है झंडा "व्यापार का उल्लंघन नियम" के रूप उम्मीद
  2. preempt त्रुटि (कहें, "select name from Foo where name = @Name" के साथ) और जो कुछ भी ऐप सर्वर है, उसे "व्यापार नियम उल्लंघन" ध्वज,
  3. समान गेंदपर्क में 2) के रूप में वापस लौटाएं: डीबी परत में निर्मित अद्वितीय बाधा का लाभ उठाएं और अंधेरे से insert into Foo, किसी भी अपवाद को पकड़कर इसे ऐप की सेवा करने के लिए जो भी हो आर के रूप में "व्यापार नियम का उल्लंघन किया" झंडा
  4. आँख बंद करके insert into Foo (जैसे 3) और कहा कि अपवाद ui, प्लस असली Exceptions के रूप में अनुप्रयोग सर्वर उठाने के व्यापार नियम उल्लंघन नहीं किया है (के रूप में 1 के खिलाफ) के लिए प्रचार करते हैं उम्मीद है। इस तरह सभी त्रुटियों को ui परत के onError() (या समान) कोड में संभाला जाता है।

मैं के बारे में 2) क्या पसंद और 3) कि व्यापार नियम उल्लंघन "फेंक दिया" कर रहे हैं, जहां वे लागू किया जाता है है: संग्रहीत proc में। मुझे 1) और 3 के बारे में क्या पसंद नहीं है) क्या मैं सोचता हूं में वे "if error.IndexOf('duplicate key')" जैसे बेवकूफ चेक शामिल हैं, जैसे वर्तमान में यूई लेयर में क्या है।

संपादित: मैं 4 की तरह), लेकिन अधिकांश लोगों केवल असाधारण परिस्थितियों में Exception रों उपयोग करने के लिए कहते हैं।

तो, आप लोगों को उदारता से व्यवसाय नियमों के उल्लंघन का प्रचार कैसे करते हैं?

1

एक संग्रहित प्रक्रिया कॉलर को त्रुटि जानकारी वापस करने के लिए RAISERROR कथन का उपयोग कर सकती है। इसका उपयोग ऐसे तरीके से किया जा सकता है जो उपयोगकर्ता इंटरफ़ेस को यह तय करने के लिए अनुमति देता है कि त्रुटि कैसे दिखाई देगी, जबकि संग्रहीत प्रक्रिया को त्रुटि का विवरण प्रदान करने के लिए अनुमति दी जा रही है।

रेज़रर को msg_id, गंभीरता और स्थिति, और त्रुटि तर्कों के सेट के साथ बुलाया जा सकता है। इस तरह इस्तेमाल होने पर, दिए गए msg_id के साथ एक संदेश sp_addmessage सिस्टम संग्रहीत प्रक्रिया का उपयोग कर डेटाबेस में दर्ज किया जाना चाहिए। यह msg_id SqlException में ErrorNumber प्रॉपर्टी के रूप में पुनर्प्राप्त किया जा सकता है जिसे संग्रहीत प्रक्रिया को कॉल करने वाले .NET कोड में उठाया जाएगा। उपयोगकर्ता इंटरफ़ेस तब तय कर सकता है कि किस प्रकार का संदेश या अन्य संकेत प्रदर्शित करना है।

इसी तरह कैसे printf बयान सी में काम करता है हालांकि, अगर आप सिर्फ UI पर वापस तर्क पारित करने के लिए इतना है कि यूआई तय कर सकते हैं कि उन्हें कैसे उपयोग करना चाहते करने के लिए त्रुटि तर्क जिसके परिणामस्वरूप त्रुटि संदेश में प्रतिस्थापित कर रहे हैं , केवल त्रुटि संदेशों को कोई पाठ नहीं है, केवल तर्क के लिए प्लेसहोल्डर हैं। एक संदेश एक स्ट्रिंग तर्क (उद्धरण में), और एक संख्यात्मक तर्क को पारित करने के लिए '% s "|% d' हो सकता है। .NET कोड इन्हें अलग-अलग विभाजित कर सकता है और उन्हें उपयोगकर्ता इंटरफ़ेस में उपयोग कर सकता है।

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

  0

मैं उस व्यक्ति को चाहता हूं जिसने इसे कम किया है और http://stackoverflow.com/questions/581994/-net-coding- मानक-and-framework-for-a-web-service/582429#582429 एक कारण देगा। एक बहुत ही अलग जवाब, एक ही परिणाम, एक मिनट के भीतर। 05 apr. 092009-04-05 16:47:00

+1

कोड जो अंततः 'RAISERROR' को कॉल करता है उसे अभी भी "बेवकूफ चेक" जैसे 'CHARINDEX (' डुप्लिकेट कुंजी ', @errorMessage)> 0' करने की आवश्यकता होगी और मुझे यह प्रश्न मिला क्योंकि मेरे उदाहरण परिदृश्य में * दो * संभावित अद्वितीय कुंजी शामिल है बाधा उल्लंघन और मैं उत्सुक था कि चाबियों के नाम या प्रासंगिक कॉलम के नामों के बिना खोज के बिना किस कुंजी का उल्लंघन किया गया है, यह निर्धारित करने का कोई तरीका था। 27 jul. 112011-07-27 19:07:06


1

मैंने कई अजाक्स आधारित अनुप्रयोगों को उपयोगकर्ता नाम जैसे फ़ील्ड पर रीयल-टाइम चेक करने के लिए देखा है (जैसे यह देखने के लिए कि यह पहले से मौजूद है) जैसे ही उपयोगकर्ता संपादन बॉक्स छोड़ देता है। मुझे डीबी बाधा के आधार पर अपवाद बढ़ाने के लिए डेटाबेस छोड़ने से बेहतर दृष्टिकोण लगता है - यह वास्तविक प्रक्रिया है क्योंकि यह वास्तविक प्रक्रिया है: मान प्राप्त करें, यह देखने के लिए जांचें कि यह वैध है या नहीं, अगर त्रुटि नहीं है, अगर कोई त्रुटि नहीं है तो जारी रखने की अनुमति दें। तो ऐसा लगता है कि विकल्प 2 एक अच्छा है।

  0

यह यूएक्स के लिए अच्छा है, लेकिन एक बड़ी दौड़ की स्थिति है कि यूई को अभी भी डेटा जमा करने के साथ सौदा करना चाहिए। 22 feb. 092009-02-22 03:38:27

  0

सबमिट पर पूर्ण सर्वर-साइड सत्यापन करके हम दौड़ की स्थिति के आसपास आते हैं। प्रति फ़ील्ड सत्यापन उपयोगकर्ता के लिए केवल 22 feb. 092009-02-22 15:53:12

  0

@ मार्क के लिए एक सुविधा है: निश्चित रूप से।मैं बस सोच रहा हूं कि लोग उल्लंघन के दौरान "पूर्ण सर्वर-साइड सत्यापन" को कैसे संभालें (डेटा जमा करने के लिए AJAX मानते हैं) - जब आप अपने अन्य उत्तर में उत्तर देते हैं, धन्यवाद। 22 feb. 092009-02-22 16:42:06


3

समस्या वास्तव में आपके सिस्टम की वास्तुकला में एक सीमा है। डेटाबेस में सभी तर्कों को दबाकर, आपको इसे दो स्थानों पर संभालने की आवश्यकता है (जैसा कि व्यापार तर्क की एक परत बनाने के विपरीत है जो यूआई को डेटाबेस के साथ जोड़ता है। फिर फिर, आपके पास व्यापार तर्क की एक परत है, तो आप सभी को खो देते हैं संग्रहीत procs में तर्क के क्या फ़ायदे। एक या दूसरे की वकालत नहीं कर। The दोनों के बारे में समान रूप से चूसना। या फिर चूसना नहीं है। आप इसे कैसे देखते पर निर्भर करता है।

कहाँ था मैं? ठीक है।

मुझे लगता है कि 2 और 3 का संयोजन शायद जाने का तरीका है।

त्रुटि को पूर्व-खाली करके आप प्रक्रियाओं का एक सेट बना सकते हैं जिसे यूआई-फेस कोड से विस्तृत कार्यान्वयन प्रदान करने के लिए कहा जा सकता है उपयोगकर्ता को आयन-विशिष्ट प्रतिक्रिया। आपको क्षेत्र-दर-मैदान आधार पर AJAX के साथ ऐसा करने की आवश्यकता नहीं है, लेकिन आप कर सकते हैं।

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

  0

यह वास्तव में 2 और 4 का संयोजन है, 4 से ट्विक के साथ कि ऐप सर्वर पर त्रुटियों को बढ़ाने के बजाय वे संग्रहीत प्रो में उठाए जाते हैं। तो संग्रहीत प्रो सभी व्यापार नियम उल्लंघन के लिए अपवाद फेंकता है (कुछ इसे स्वयं पकड़ा, कुछ डीबी इसके लिए पकड़ा गया)। मुझे पसंद है। 22 feb. 092009-02-22 13:13:52

  0

आप सही हैं ... 23 feb. 092009-02-23 01:47:53


2

# 4 की रक्षा में, SQL सर्वर में त्रुटि गंभीरता स्तरों का पूर्व क्रमबद्ध पदानुक्रम है। चूंकि आप इंगित करते हैं कि त्रुटियों को संभालने के लिए यह ठीक है, जहां तर्क है, मैं एसपी और यूआई अमूर्तता के बीच सम्मेलन द्वारा इसे अतिरिक्त युग्मन के समूह को जोड़ने के बजाय इसे संभालने के इच्छुक हूं। खासकर जब से आप एक मूल्य और एक स्ट्रिंग दोनों के साथ त्रुटियां बढ़ा सकते हैं।


5

हम डेटाबेस में अपना व्यावसायिक तर्क नहीं करते हैं, लेकिन हमारे पास हमारे सभी सत्यापन सर्वर-पक्ष हैं, निम्न स्तर के डीबी सीआरयूडी संचालन उच्च स्तर के व्यापार तर्क और नियंत्रक कोड से अलग हैं।

हम आंतरिक रूप से करने का प्रयास करते हैं, Validation.addError(message,[fieldname]) जैसे कार्यों के साथ एक सत्यापन ऑब्जेक्ट के आसपास गुजरता है। विभिन्न आवेदन परतों इस वस्तु पर अपनी मान्यता परिणाम संलग्न करें और फिर हम Validation.toJson() फोन एक परिणाम है कि इस तरह दिखता है निर्माण करने के लिए:

{ 
    success:false, 
    general_message:"You have reached your max number of Foos for the day", 
    errors:{ 
     last_name:"This field is required", 
     mrn:"Either SSN or MRN must be entered", 
     zipcode:"996852 is not in Bernalillo county. Only Bernalillo residents are eligible" 
    } 
} 

जनरल के रूप में अलग-अलग क्षेत्रों से संबंधित रूप में अच्छी तरह संदेशों को प्रदर्शित करने यह आसानी से संसाधित किया जा सकता ग्राहक के पक्ष संदेश।

बाधा उल्लंघन के संबंध में हम # 2 का उपयोग करते हैं, यानी हम सम्मिलन/अद्यतन से पहले संभावित उल्लंघनों की जांच करते हैं और सत्यापन ऑब्जेक्ट में त्रुटि जोड़ते हैं।

  0

मुझे पता है कि वोटिंग ऑपरेशन के लिए एसओ क्या करता है। प्रतिक्रिया में "सफलता" और "संदेश" फ़ील्ड हैं। लेकिन अगर आप बहुत जल्दी टिप्पणियां जमा करते हैं तो वे 500 सर्वर अपवाद फेंक देते हैं और यूई इसे पकड़ता है (यानी मेरा कोड उदाहरण क्या करता है, जिसे मैं पसंद नहीं करता)। 22 feb. 092009-02-22 16:32:47

  0

हालांकि मुझे इस दृष्टिकोण को पसंद है, और डीबी में संभाले गए व्यवसाय नियमों के चेक के साथ भी ऐसा करना असंभव नहीं होगा। ऐप सर्वर को सिर्फ सभी प्रतिक्रियाओं को उस मानक पर अनुवाद करना होता है जिसे ui संभाल सकता है। जो परवाह करने के लिए एक बुरी बात नहीं है। 22 feb. 092009-02-22 16:38:28


1

इस तरह मैं बातें करते हैं, हालांकि यह आपके लिए सबसे अच्छा नहीं हो सकता है:

मैं आम तौर पर, पूर्व रिक्तिपूर्व मॉडल के लिए जाना है, हालांकि यह आपके आवेदन वास्तुकला पर एक बहुत निर्भर करता है।

मेरे लिए (मेरे पर्यावरण में) मध्य (व्यापार वस्तुओं) स्तर में अधिकांश त्रुटियों की जांच करना समझ में आता है। यह वह जगह है जहां अन्य सभी व्यवसाय-विशिष्ट तर्क होते हैं, इसलिए मैं यहां तक ​​कि मेरे बाकी तर्कों को भी रखने की कोशिश करता हूं। मैं अपने ऑब्जेक्ट्स को जारी रखने के लिए डेटाबेस के बारे में सोचता हूं।

जब सत्यापन की बात आती है, तो सबसे आसान त्रुटियां जावास्क्रिप्ट (स्वरूपण, फ़ील्ड लम्बाई इत्यादि) में फंस सकती हैं, बेशक आप कभी भी यह नहीं मानते कि उन त्रुटि जांच हुई हैं। उन त्रुटियों को सर्वर-साइड कोड की सुरक्षित, अधिक नियंत्रित दुनिया में भी चेक किया जाता है।

व्यवसाय नियम (जैसे कि "आप प्रति दिन इतने सारे फ़ूज़ हो सकते हैं") व्यावसायिक ऑब्जेक्ट परत में सर्वर-साइड कोड में चेक-इन हो जाते हैं।

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

इस प्रकार मेरा डेटाबेस केवल सरल, डेटा-केंद्रित नियमों के खिलाफ स्वयं को सुरक्षित रखता है जो इसे संभालने के लिए अच्छी तरह से सुसज्जित है; अधिक परिवर्तनीय, व्यवसाय-उन्मुख नियम रिकॉर्ड्स की भूमि के बजाय वस्तुओं की भूमि में रहते हैं।

  0

अच्छा। उत्सुक हालांकि: दौड़ की स्थिति के बारे में आप क्या करते हैं जहां मध्य स्तर में एक चेक गुजरता है, लेकिन डेटा स्तर पर विफल रहता है (कहने के कारण, एक और थ्रेड इसे पंच पर मार रहा है)? 22 feb. 092009-02-22 23:30:30

  0

हाँ, यह इस दृष्टिकोण में पूरी तरह से कमजोरी है। मेरे विशेष माहौल में, यह एक दुर्लभ मामला है कि हमें इसके बारे में चिंता करने की आवश्यकता नहीं है। इसके परिणामस्वरूप बदसूरत अपवाद, सच होगा, लेकिन डेटाबेस बरकरार रहेगा। 23 feb. 092009-02-23 06:16:09