2012-01-29 19 views
22

कल्पना करें कि कुछ आईडी-डेटा कुछ संसाधन-संसाधन को संग्रहीत करता है जो कुछ आईडी के साथ तीन संलग्नक (उदा। पीडीएफ) प्रति डेटाम स्टोर करता है।एकाधिक संसाधनों के विश्वसनीय परमाणु अद्यतन?

यूआरएल स्कीम

data/{id}/attachment1 
data/{id}/attachment2 
data/{id}/attachment3 

एक RESTful API संलग्नक प्राप्त/PUT प्रदान करने के लिए मौजूद है/सर्वर साइड पर CRUD संचालन को लागू करने के संचालन DELETE है।

दे आईडी 123 हो, मैं एक ऑपरेशन जहां

  • attachment1 एक नया लगाव की जगह प्रदर्शन करने के लिए चाहते हैं (जैसे कि GET file/123/attachment1 रिटर्न एक नया लगाव)
  • attachment2 हटा दी जाती है (जैसे कि कि GET file/123/attachment2 रिटर्न 404)
  • अटैचमेंट 3 अपरिवर्तित बनी हुई है।

अद्यतन परमाणु होना चाहिए - पूरा अद्यतन सर्वर या कुछ भी नहीं द्वारा किया जाता है।

एक साधारण PUT file/123/attachment1 और DELETE file/123/attachment2 लागू करना परमाणु नहीं है, क्योंकि क्लाइंट PUT के बाद क्रैश हो सकता है और सर्वर के पास कोई संकेत नहीं है कि उसे इस मामले में रोलबैक करना चाहिए।

तो मैं ऑपरेशन को एक यथार्थ तरीके से कैसे कार्यान्वित करूं?

मैं दो समाधान के बारे में सोचा है, लेकिन वे दोनों 100% RESTful होने लगते नहीं है:

  • उपयोग PATCH (रखा जा सकता है, लेकिन PATCH बेहतर एक आंशिक अद्यतन के शब्दों को दर्शाता है) बहुखण्डीय साथ/डेटा/123 पर फॉर्म-डेटा: मल्टीपार्ट/फॉर्म-डेटा एक नई "संलग्नक 1" और फ़ील्ड से जुड़े "एप्लिकेशन/पीडीएफ" से जुड़ी इकाइयों का एक अनुक्रम है जो इंगित करने के लिए शून्य-मूल्य का प्रतिनिधित्व करेगा अनुलग्नक 2 का विलोपन।

हालांकि यह atomicity सुनिश्चित करता है, मुझे शक है इस RESTful है के बाद से मैं ओवरलोड जो वर्दी इंटरफ़ेस बाधा का उल्लंघन करती है अलग पैरामीटर सूची का उपयोग करने PATCH विधि,।

  • लेनदेन का प्रतिनिधित्व करने वाले संसाधन का उपयोग करें। मैं डेटा आईडी 123 को एक लेन-देन-यूआरएल पर पोस्ट कर सकता हूं जो लेनदेन संसाधन सर्वर पर संग्रहीत डेटा-संसाधन की मौजूदा स्थिति की एक प्रति का प्रतिनिधित्व करेगा, उदाहरण के लिए सर्वर पर संग्रहीत करता है, उदा। लेन-देन/डेटा/123। अब मैं PUT और को इस अस्थायी संसाधन (उदा। DELETE transaction/data/123/attachment2) के अनुलग्नकों पर हटा सकता हूं और को लेनदेन/डेटा/123 पर PUT के माध्यम से सर्वर के संसाधन के इस संस्करण की प्रतिबद्धता को संवाद कर सकता हूं। यह परमाणुता सुनिश्चित करता है जबकि कई क्लाइंट से निपटने के लिए अतिरिक्त सर्वर साइड तर्क लागू करता है, जो समान संसाधन और क्रैश किए गए क्लाइंट को बदलता है जो कभी नहीं किया जाता है।

हालांकि यह आरईएसटी के साथ संगत लगता है, ऐसा लगता है कि यह स्टेटलेसनेस की बाधा का उल्लंघन करता है।लेनदेन संसाधन की स्थिति सेवा राज्य नहीं है बल्कि आवेदन राज्य है, क्योंकि प्रत्येक लेनदेन संसाधन एक ग्राहक से जुड़ा हुआ है।

मैं यहां फंस गया हूं, इसलिए कोई विचार उपयोगी होगा, धन्यवाद!

+2

दूसरे दृष्टिकोण में डेटा परिवर्तनों का एक अच्छा इतिहास प्रदान करने का लाभ है और आपको कुछ लॉगिंग छोड़ने की सुविधा मिल सकती है। – Jasper

+0

@mtsz मैं अभी इस समस्या से जूझ रहा हूं। मुझे आपके द्वारा चुने गए उत्तर को पसंद है, लेकिन यह एक लघु, अस्थायी जीवनकाल के साथ एक लेनदेन संसाधन बनाने के लिए बहुत सारे काम की तरह लगता है। क्या आपको लगता है कि परमाणु लेनदेन को "स्विचरू" जैसे नाम देने के लिए बुरा होगा और उस लेनदेन को करने वाली एक विशिष्ट वेब सेवा बनाएं? उदाहरण के लिए, {fileId: 123} के शरीर के साथ POST/doSwitcheroo .... इस सेवा में आईडी 123 –

उत्तर

15

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

POST /transaction 

HTTP/1.1 301 Moved Permanently 
Location: /transaction/1234 

अब आप लेन-देन संसाधन एक बेहतरीन सुविधा है कि है:

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

लेनदेन प्रगति पर है, यह सिर्फ एक और संसाधन है। यहां कोई ग्राहक राज्य नहीं है। कोई भी इस लेनदेन में जोड़ सकता है।

जब यह सब किया जाता है, तो सर्वर यहां कुछ आंतरिक लेनदेन तंत्र का उपयोग करके परिवर्तनों को लागू करता है जो यहां दायरे से बाहर है।

आप एटैग जैसी चीजों को कैप्चर कर सकते हैं और लेन-देन उप क्रियाओं में संशोधित शीर्षलेखों को कैप्चर कर सकते हैं ताकि जब वे सभी लागू हों, तो आप जानते हैं कि आपकी पीठ के पीछे कुछ नहीं बदला है।

+0

उचित लगता है। शायद इस मामले में "आवेदन राज्य" की धारणा थोड़ी अधिक अतिरंजित है और यह "प्रथम श्रेणी नागरिक" सामान्य सेवा स्थिति है। [रिचर्डसन एंड रूबी] (http://shop.oreilly.com/product/9780596529260.do) इस तरह के समाधान को बढ़ावा देते हैं, हालांकि यह कई सर्वरों के साथ एक परिदृश्य में लागू होता है। मुझे आश्चर्य है, रॉय फील्डिंग क्या करेगी? :) – mtsz

+6

आप लेन-देन को उसी तरह देख सकते हैं जैसे आप एक शॉपिंग कार्ट देख सकते हैं। एक शॉपिंग कार्ट में, एक ग्राहक समय के साथ अपने लेनदेन का निर्माण करता है, और फिर वे चेकआउट प्रक्रिया के माध्यम से जाते हैं जो अंततः उनके साथ "पुष्टि" या "रद्द करने" के साथ समाप्त होता है। जब आप उन शब्दों में उस शब्दावली के साथ देखते हैं, तो यह अधिक समझ में आता है। लेकिन 10,000 फीट पर, वे मूल रूप से एक ही समस्या है। "यहां उन सभी चीजों की एक सूची दी गई है जो मैं करना चाहता हूं - अब, जाओ!" तथ्य यह है कि एक शॉपिंग कार्ट एक विशिष्ट उपयोगकर्ता के लिए बाध्य है एक सुरक्षा/पहचान मुद्दा है, न कि "राज्य" बनाम "स्टेटलेसनेस" मुद्दा। –

+0

मैंने इस समाधान को लागू किया है जो अच्छी तरह से काम करता है। आपको "सूची" के साथ संभव नहीं, डेटा को मुक्त करने के बिना "रेस संपादित करें" को हल करने का लाभ मिलता है। – mtsz

5

बहुत ही रोचक सवाल। लूगानो (स्विट्जरलैंड) विश्वविद्यालय में एक सीएस प्रोफेसर इस स्थिति के बारे कुछ स्लाइडों लिखा है:

http://www.slideshare.net/cesare.pautasso/atomic-transactions-for-the-rest-of-us

हालांकि मैं वास्तव में लगता है कि समाधान वह प्रदान पूरी तरह से RESTful है क्योंकि यह वास्तव में पर स्टेटलेस प्रतीत नहीं होता है नहीं कर रहा हूँ सर्वर की ओर।

, ईमानदार होने के नाते के बाद से लेनदेन ही कई राज्यों द्वारा रचित है, मुझे नहीं लगता कि इस समस्या के लिए एक पूरी तरह से RESTful समाधान हो सकता है।

+1

के साथ फ़ाइल पर ऊपर वर्णित कार्रवाइयों को परमाणु रूप से निष्पादित करने का तर्क होगा। मैंने अपने पेपर को स्किम किया (विश्वसनीय पर परमाणु लेनदेन के लिए वितरित सेवा)। वे एक समन्वयक संसाधन के साथ एक कोशिश-रद्द/पुष्टि प्रोटोकॉल का प्रस्ताव देते हैं जो आखिरकार सभी भाग लेने वाले संसाधनों (या पूर्व राज्य की वसूली शुरू करता है) पर परिवर्तन की पुष्टि करता है। संसाधन सर्वर वितरित किए जाते हैं, इसलिए मेरा दायरा थोड़ा बड़ा होता है। फिर भी यह टीसीसी प्रोटोकॉल उपरोक्त वर्णित दूसरे समाधान के समान होना चाहिए। कम से कम वे अवधारणा को पिछले राज्य को पुनर्प्राप्त करने के साधनों को जोड़कर सेवा राज्य में बदलकर अवधारणा को हल कर सकते हैं। शायद यही तरीका है। – mtsz

0

अपने यूआरआई मानते हुए श्रेणीबद्ध हैं:

PUT data/{id} 
[attachment2,attachment3] 

आपकी समस्या यह है कि attachment1/2/3 एक भयानक पहचानकर्ता है। एक सूचकांक कभी भी आपके यूआरआई का हिस्सा नहीं होना चाहिए।

+0

परिदृश्य को अधिक सामान्य बनाने के लिए पहचानकर्ता मनमानी हैं। एक ठोस परिदृश्य की कल्पना करें जहां आपके पास अपेक्षित मॉडल, वर्णन, चित्र इत्यादि के साथ डेटा ब्लब्स हैं। मैं नहीं देखता कि आपका समाधान एकाधिक संलग्न संसाधनों के निरंतर अद्यतन की समस्या को हल करता है, क्योंकि PUT अनुक्रमिक हैं? – mtsz

+0

संसाधन के रूप में अनुलग्नकों की अपनी सूची के बारे में सोचें। आप सामग्री और ऑर्डर कर रहे हैं। 1 ऑपरेशन – noah

+0

इसलिए, यदि मैं सही ढंग से समझता हूं, तो आप एक मीडिया प्रकार का अनुक्रमण करने का विकल्प चुनते हैं, जैसे मल्टीपार्ट/फॉर्म-डेटा या कस्टम प्रकार। चूंकि मेरे मूल प्रश्न में यह समाधान था, इसलिए यह पढ़ना दिलचस्प होगा कि यह समाधान कैसे उचित है। – mtsz

0

मुझे अनुभव नहीं हुआ है, लेकिन मुझे समाधान के लिए एक विचार है क्योंकि मुझे विकास में इस समस्या का सामना करना पड़ रहा है।

सबसे पहले, मैं एक घर (संसाधनों के साथ सर्वर) में फ्रेड 1 को एक संदेश भेजकर (क्लाइंट) के समानता का उपयोग करता हूं, जिसे मैं चाहता हूं कि वह प्रकाश स्विच बंद करें (संसाधन के हिस्से को बदल दें) और चालू करें केतली (संसाधन के दूसरे हिस्से की स्थिति बदलें)। हल्के स्विच फ्रेड को बंद करने के बाद, दुर्भाग्य से, दिल का दौरा पड़ता है।

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

यह शुरुआत है कि मैं इसे कैसे करूँगा, स्पष्ट रूप से चिंता का दायरा है, लेकिन अगर मैंने पहले से ही अपना दायरा परिभाषित किया है (मुझे केवल प्रकाश स्विच और केतली में दिलचस्पी है) तो मुझे पर्याप्त जानकारी होनी चाहिए (प्रकाश स्विच और केतली की स्थिति को जानना) फ्रेड 2 को निर्देश के लिए उपयोगकर्ता के पास वापस जाने के बिना एक नया आदेश देने के लिए।

यह आवाज कैसा है?

+0

दिलचस्प, लेकिन समस्याग्रस्त: जब प्रकाश को बंद करने के बाद फ्रेड को दिल का दौरा पड़ता है, तो आपके पास असंगत स्थिति होती है।यह तब तक असंगत होगा जब तक आप अपने ग्राहक का उपयोग करके राज्य की जांच करें और अगले फ्रेड को एक और संदेश भेजें (जो उम्मीद नहीं करेगा)। अगर आपका ग्राहक मरने के ठीक बाद मर जाता है तो क्या होगा? फिर इच्छित राज्य हमेशा के लिए खो जाता है। अन्य ग्राहकों को वर्तमान असंगत स्थिति के साथ सामना करना पड़ेगा जो गंभीर परेशानी का कारण बन सकता है ... – mtsz

+0

वास्तव में दिलचस्प :) डेटाबेस के बारे में क्या - वे इसे कैसे करते हैं? एक डेटाबेस को आंतरिक रूप से परमाणु होना चाहिए, तो शायद यह देखने के लिए एक और अच्छी जगह है। मैं PostgreSQL चला रहा हूँ तो दस्तावेज की जांच करेगा। PostgreSQL परमाणु का एक लिंक यहां दिया गया है: http://www.postgresql.org/files/developer/transactions.pdf – tentimes

+0

आप डेटाबेस सत्र (जैसे एसक्यूएल सत्र) की धारणा अपना सकते हैं: आपके सत्र के अंदर लागू सभी संशोधन हैं जब तक आप अपना सत्र नहीं करते, तब तक प्रदर्शन नहीं किया जाता है। जब किसी एक संशोधन के साथ कुछ बुरा होता है, तो सत्र वापस ले जाता है और पिछला संगत राज्य संरक्षित होता है। तो जब प्रकाश स्विच के मोड़ के बाद फ्रेड मर जाता है, तो वह एक हार्टफेलर एक्सेप्शन फेंकता है जो पकड़ा जाता है, एक सत्र रोलबैक ट्रिगर करता है और प्रकाश फिर से चला जाता है;) – mtsz