2012-07-09 13 views
6

मेरे पास दो डेटाबेस कनेक्शन हैं, जिनका उपयोग मेरे अधिकांश एप्लिकेशन डेटा के लिए किया जाता है, और एक जिसे केवल पढ़ने के लिए उपयोग किया जाता है।Yii केवल पढ़ने के लिए डेटाबेस कनेक्शन को प्रतिबंधित करें

हालांकि मैं अपने डेटाबेस उपयोगकर्ता खाते को केवल पढ़ने की अनुमति देने के लिए सेट कर सकता हूं, इस प्रणाली को प्रशासित करने वाले अन्य लोग भी हैं, और मैं एप्लिकेशन स्तर पर कुछ रिडंडेंसी चाहता हूं ताकि वाईआई के मानक ActiveRecord कक्षाओं का उपयोग करके अनजान लिखने को पूरी तरह से रोका जा सके।

फ़ोरम पर इस जानकारी की जानकारी मिली, लेकिन यह सोच रहा था कि कोई यह पुष्टि कर सकता है कि यह एक अच्छा दृष्टिकोण है और/या किसी अन्य का सुझाव है।

public function onBeforeSave($event) 
{ 
    $this->db = Yii::app()->masterDb; 
} 

public function onAfterSave($event) 
{ 
    $this->db = Yii::app()->db; 
} 

http://www.yiiframework.com/forum/index.php/topic/5712-active-record-save-to-different-server-load-balancefail-over-setup/

+2

एक अलग डीबी उपयोगकर्ता का उपयोग करने के लिए समझदार तरीका है। –

+1

@ tereško ... और पूरी तरह से गारंटी देने का एकमात्र तरीका है कि कोई भविष्य कोड इस "सम्मेलन" को तोड़ता है ... – Ron

+0

मैं मानता हूं कि एक पाठक डीबी उपयोगकर्ता सबसे सुरुचिपूर्ण समाधान है, हालांकि मुझे अनावश्यकता चाहिए क्योंकि मैं लोगों पर भरोसा नहीं करता सिस्टम को प्रशासित करना 100% –

उत्तर

4

कि लिंक आप Yii मंचों के लिए प्रदान की प्रति हो जाएगा लगता है, वहाँ एक विस्तार है कि आप के लिए यह संभालती है: http://www.yiiframework.com/extension/dbreadwritesplitting

मैं शायद पहला यह है कि इस पर गौर करना चाहते हैं, अगर आपने बहुत सारे एआर मॉडल मिल गए। आप एक अन्य विकल्प के रूप में व्यवहार मार्ग (जैसा कि उस मंच पोस्ट में सुझाया गया है) जा सकते हैं।

लेकिन जो कुछ भी आप करते हैं, आप पहले से ओवरवॉइड करना चाहते हैं, पहले सेवसेव/ऑनएफ्टरसेव के बजाय सहेजें। वे विधियां ईवेंट को ट्रिगर करने के लिए हैं, न सिर्फ अपना खुद का विशेष कोड चला रही हैं। और, प्रति another one of the forum posts पर, आपको एक स्थिर कॉल का उपयोग करके अपने एआर डीबी वैरिएबल को सेट करने की आवश्यकता होगी। तो सर्गेई का कोड वास्तव में होना चाहिए:

class MyActiveRecord extends CActiveRecord 
{ 
    ... 
    public function beforeSave() 
    { 
     // set write DB 
     self::$db = Yii::app()->masterDb; 

     return parent::beforeSave(); 
    } 

    public function afterSave() 
    { 
     // set read db 
     self::$db = Yii::app()->db; 

     return parent::beforeSave(); 
    } 
    ... 
} 


class User extends MyActiveRecord {} 
class Post extends MyActiveRecord {} 
... 
+0

वह एक्सटेंशन बहुत निफ्टी है, मुझे इसके बारे में कुछ और पढ़ना होगा। –

2
class MyActiveRecord extends CActiveRecord 
{ 
... 
public function onBeforeSave($event) 
{ 
    // set write DB 
    $this->db = Yii::app()->masterDb; 
} 

public function onAfterSave($event) 
{ 
    // set read db 
    $this->db = Yii::app()->db; 
} 
... 
} 


class User extends MyActiveRecord {} 
class Post extends MyActiveRecord {} 
... 

यू कि जिस तरह से कोशिश करने के लिए है :) लेकिन IMHO यह काफी अच्छा नहीं है। मैं कुछ कीड़े या दोष

+0

इस समाधान को देखने वाले किसी भी अन्य के भविष्य के संदर्भ के लिए, मैंने इस पोस्ट के हिस्सों को छोड़ने के लिए धन्यवाद। आप किस प्रकार की बग/दोष का जिक्र कर रहे हैं? –

+0

@ जोहानज़, एकोर्नॉम कहते हैं: 'पर पहले सेव/ऑनएफ्टरसेव। वे विधियां घटनाओं को ट्रिगर करने के लिए हैं, न सिर्फ अपना विशेष कोड चला रही हैं। ' मेरा मतलब है – Sergey

2

एक परिदृश्य को देखते हुए जहां आपका दास मास्टर के साथ अपडेट नहीं हो सकता है, तो आप समस्याओं में भाग ले सकते हैं। क्योंकि डेटा अपडेट करने के बाद आप शायद पुराने संस्करण से पढ़ लेंगे।

जबकि मंच में दिए गए दृष्टिकोण बहुत साफ हैं और लेखकों द्वारा लिखे गए हैं जो ज्यादातर वाईआई जादूगर हैं। मेरे पास एक विकल्प भी है। आप की तरह

public function getDbConnection(){ 
    if (Yii::app()->user->hasEditedData()) { # you've got to write something like this(!) 
    return Yii::app()->masterDb; 
    } else { 
    return Yii::app()->db; 
    } 
} 

एआर में getDbConnection() विधि को भी पार कर लेकिन आप अभी भी जब डेटाबेस कनेक्शन स्विचिंग सावधान रहना होगा।