2012-12-12 10 views
9

मेरे डेटासेट क्लाइंट एप्लिकेशन में मैं अपने तरीकों और प्रदाता कनेक्शन के लिए 1 TSQLConnection का उपयोग करता हूं। कनेक्शन खो जाने पर समस्याएं उत्पन्न होती हैं। दोनों TSQLConnection.Connected और TSQLConnection.ConnectionState इसे पकड़ नहीं है।क्लाइंट-सर्वर डिस्कनेक्ट के माध्यम से SQLConnection/Datasnap का प्रबंधन

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

मैंने अपने सर्वर विधियों के लिए अपने SQL कनेक्शन को प्रबंधित करने के लिए एक फ़ंक्शन बनाया है। लेकिन अधिक समस्या तब उत्पन्न होती है जब उदाहरण के लिए क्लाइंटडेटसेट बंद होता है जो TDSProviderConnection के माध्यम से जुड़ा होता है।

प्रश्न: आप अपने क्लाइंट एप्लिकेशन को TSQLconnection पर किसी भी डिस्कनेक्ट को सुरक्षित रूप से पकड़ने के लिए कैसे प्रबंधित करते हैं। क्यू: आप डाउनटाइम का प्रबंधन कैसे करते हैं, और आप सहेजे गए क्लाइंट स्थिति के साथ क्या करते हैं।

डाउनटाइम के बाद पुन: कनेक्शन समस्या नहीं है।

सर्वर विधि को कॉल करते समय: यह अपवाद फेंक देगा।

tmpM:=TServerMethodsClient.Create(MYTSQLCONNECTION.dbxconnection,true); 

तो मैं डमी विधि के साथ अपने डेटामैड्यूल से TSQLCONNECTION प्राप्त करने के लिए अगली विधि लिखता हूं।

function TDMForm.DSConnection: TSQLConnection; 
var 
    tmpM:TServerMethodsClient; 
begin 
    result:=nil; 
    if assigned(MYTSQLCONNECTION) then begin 
    tmpM:=TServerMethodsClient.Create(MYTSQLCONNECTION.dbxconnection,true); 
    try 
     try 
     tmpM.Ping; 
     result:=MYTSQLCONNECTION 
     except 
     ReconnectForm.ShowModal; // has a reconnect button that tries to reconnect + shutdownbutton 
     if ReconnectForm.modalresult=mrOK then 
      result:=MYTSQLCONNECTION 
     else 
      MainForm.Close; 
     end; 
    finally 
     tmpm.Free; 
    end; 
    end; 
end; 

मैं विधि इस तरह से लिखा है, क्योंकि केवल पता लगाने के लिए अगर कनेक्शन खो जाता है जिस तरह से डमी विधि है जो के माध्यम से होता है ... एक ही त्रुटि फेंक तो मैं पुनः कनेक्ट या करीबी कार्यक्रम के लिए क्वेरी कर सकते हैं होगा।

संपादित करें: (मैं सामान्य जवाब और दिशा निर्देशों, क्या करें किसी तरह की उम्मीद कर रहा हूँ और अभी मैं क्या पल में कर रहा हूँ नहीं दिखा मेरी कोड की नहीं एक सुधार, यह करने के लिए।।)

उत्तर

3

हम एक ही मुद्दे से संघर्ष कर रहे थे - यह पता लगाने के लिए कि कनेक्शन कब टूट गया है, और कैसे गहन रूप से दोबारा जुड़ना है। यहां हम क्या कर रहे हैं, जो हमारे लिए बहुत सफल साबित हुआ है।

हमारे उपयोगकर्ता डेटा पुनर्प्राप्त करने और परिवर्तन करने के लिए DataSnap सर्वर से कनेक्ट होते हैं। में OnBeforePost और OnBeforeDelete ईवेंट हैंडलर के माध्यम से सभी रिकॉर्ड बनाता है, अद्यतन और हटाए जाते हैं।

जब से तुम पता नहीं लगा सकता जब ग्राहक जबरन DataSnap सर्वर से डिस्कनेक्ट कर दिया गया है जब तक आप सर्वर के साथ संवाद और पता लगाने के लिए कि कनेक्शन विच्छेद कर दिया गया है की कोशिश, हम अपने अनुप्रयोग में मुख्य रूप के लिए एक TApplicationEvents जोड़ा और OnException घटना के लिए एक ईवेंट हैंडलर लिखा। जब हम EIdSocketError देखते हैं, तो हम जानते हैं कि कनेक्शन मर चुका है, इसलिए हम उपयोगकर्ता को एक संदेश दिखाते हैं और फिर Abort पर कॉल करते हैं ताकि Post या Delete स्थानीय डेटासेट में नहीं होगा। उपयोगकर्ता पुनः लॉगिन करने में सक्षम है और फिर या को अपनी पिछली क्रिया पूरी करने के लिए फिर से हटाएं।

procedure TMainForm.AppEventsException(Sender: TObject; E: Exception); 
begin 
    if E is EIdSocketError then 
    begin 
    AppEvents.CancelDispatch; 
    MessageDlg('The connection to the database was lost. You must log in before you retry the failed action. Actual error message:'#13#10#13#10 + E.Message, mtError, [mbOK], 0); 
    Abort; 
    end; 

    if E is TDBXError then 
    begin 
    AppEvents.CancelDispatch; 
    MessageDlg('The database returned an error. If you cannot correct the issue, please contact customer service with the following database error message:'#13#10#13#10 + E.Message, mtError, [mbOK], 0); 
    Abort; 
    end; 

    // Show any other unhandled exceptions 
    Application.ShowException(E); 
end; 

TDBXError, एक और एक हम जाल है, क्योंकि यह आम तौर पर एक डीबी त्रुटि हुई, एक विदेशी कुंजी या अद्वितीय कुंजी उल्लंघन की तरह का अर्थ है:

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

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

यह सब आपके पहले प्रश्न का उत्तर देता है ... किसी दिन, हम एक ऑफ़लाइन मोड लागू करेंगे जहां TClientDataSet उपयोगकर्ता के एचडीडी में सहेजा जा सकता है, और अगली बार जब वे लॉग इन करेंगे, हम सभी स्थानीय रूप से आवेदन करने के लिए एक सिंक करेंगे सहेजे गए परिवर्तन लेकिन हमने अभी तक ऐसा नहीं किया है - इसलिए मेरे पास आपके दूसरे प्रश्न का अच्छा जवाब नहीं है।

+0

आप कहते हैं "उपयोगकर्ता फिर से लॉगिन करने में सक्षम है" लेकिन आप यह नहीं कहते कि आपने यह कैसे किया? अपने स्वयं के डेटासैप ऐप में, TSQLConnection1 को भी एक कॉल। कनेक्ट किया गया: = गलत, अपवाद (10053) बढ़ाता है क्योंकि यह सर्वर को बताने की कोशिश कर रहा है (जो अब और नहीं है) कुछ। मैं यहां कैच -22 में हूं। आप _that_ के आसपास कैसे पहुंचे? – nolaspeaker

+1

@ नोलास्पीकर - चूंकि मुझे पता है कि मैं पुनः प्रमाणित करने जा रहा हूं, मुझे वास्तव में अपवाद की परवाह नहीं है। तो मैं बस 'sqlcon कोशिश करें। बंद करो; अंत को छोड़कर; ', जो कोई अपवाद खाता है। फिर मैं चुपचाप फिर से प्रमाणीकृत कर सकता हूं या उपयोगकर्ता को मैन्युअल रूप से लॉग इन करने के लिए लॉगिन संवाद को फिर से प्रमाणित कर सकता हूं। –

+0

हां, यह संभालना मेरे लिए भी हुआ - मैंने आपको प्रश्न पूछने के बाद! :-) उत्तर देने के लिये धन्यवाद। – nolaspeaker

संबंधित मुद्दे