2012-11-17 18 views
5

मौजूद नहीं है तो मैं थोड़ा उलझन में हूं। मैं अपने प्रत्यक्ष मेल सेवा के भीतर सक्रिय रूप से PHP रेडबीन का उपयोग ओआरएम के रूप में करता हूं और मैं उत्सुक परिस्थिति में चलता हूं - मेरे पास अद्वितीय कुंजी बाधा (यानी ग्राहक_आईडी, डिलीवरी_आईडी) और दो स्क्रिप्ट्स हैं जो इस तालिका में डेटा लिख ​​रही हैं। वहाँ स्रोत कोड है कि डालने है या अद्यतन तालिका है:PHP रेडबीन स्टोर बीन यदि

public static function addOpenPrecedent($nSubscriberId, $nDeliveryId) 
{ 
    $oOpenStatBean = \R::findOrDispense('open_stat', 'delivery_id = :did AND subscriber_id = :sid', array(':did' => $nDeliveryId, ':sid' => $nSubscriberId)); 

    $oOpenStatBean = array_values($oOpenStatBean); 
    if (1 !== count($oOpenStatBean)) { 
     throw new ModelOpenStatException(
      "Ошибка при обновлении статистики открытий: пара (delivery_id, 
      subscriber_id) не является уникальной: ($nDeliveryId, $nSubscriberId)."); 
    } 

    $oOpenStatBean = $oOpenStatBean[0]; 
    if (!empty($oOpenStatBean->last_add_dt)) { 
     $oOpenStatBean->precedent++; 
    } else { 
     $oOpenStatBean->delivery_id = $nDeliveryId; 
     $oOpenStatBean->subscriber_id = $nSubscriberId; 
    } 

    $oOpenStatBean->last_add_dt = time('Y-m-d H:i:s'); 
    \R::store($oOpenStatBean); 
} 

यह कहा जाता है दोनों दो स्क्रिप्ट से। और मुझे इस तालिका पर समय-समय पर भ्रष्टाचार के साथ समस्याएं हैं, क्योंकि दौड़ की स्थिति होती है। मैं एसक्यूएल "डुप्लिकेट कुंजी अपडेट पर INSERT" सुविधा के बारे में जानता हूं। लेकिन मैं अपने ओआरएम का पूरी तरह से उपयोग कर एक ही परिणाम कैसे प्राप्त कर सकता हूं?

+2

जो आप करने की कोशिश कर रहे हैं उसे "अपरर्ट" कहा जाता है। इसके लिए googling कोशिश करें। मुझे इसके बारे में यह चर्चा मिली है: https://github.com/gabordemooij/redbean/issues/160 –

उत्तर

3

वर्तमान, कि मैं अगर पता है, Redbean एक

INSERT ON DUPLICATE KEY UPDATE 
इस की चर्चा टिप्पणियों के ऊपर इंगित करता है कि Redbean के डेवलपर समझता है Upsert एक व्यापार तर्क बात यह है कि अपवित्र हैं होने के लिए में उद्धृत के रूप में

जारी नहीं करेगा ORM के अंतरावस्था। ऐसा कहा जा रहा है, अगर किसी को कस्टम क्वेरी राइटर या Documentation प्रति प्लगइन के साथ रेडबीन का विस्तार करना है तो यह संभवतः प्राप्त करने योग्य है। मैंने यह कोशिश नहीं की है क्योंकि ओआरएम के आंतरिक और प्लगइन के साथ गड़बड़ किए बिना नीचे दी गई विधि आसानी से इस व्यवहार को प्राप्त करती है, हालांकि, यह आवश्यक है कि आप लेन-देन और मॉडल और कुछ अतिरिक्त प्रश्नों का उपयोग करें।

असल में, R :: store() पर कॉल करने से पहले या तो R :: लेनदेन() या R :: start() के साथ अपना लेनदेन शुरू करें। फिर अपने "FUSE" डी मॉडल में, एक क्वेरी चलाने के लिए "अद्यतन" FUSE विधि का उपयोग करें जो डुप्लिकेशंस की जांच करता है और आवश्यक पंक्तियों को लॉक करते समय मौजूदा आईडी पुनर्प्राप्त करता है (यानी अद्यतन के लिए चयन करें)। यदि कोई आईडी वापस नहीं आती है, तो आप अच्छे होते हैं और बस अपने नियमित मॉडल सत्यापन (या इसकी कमी) सामान्य रूप से जारी रहते हैं और वापस आते हैं। यदि कोई आईडी पाई जाती है, तो बस $-> बीन-> आईडी को लौटाए गए मूल्य पर सेट करें और रेडबीन INSERT के बजाय अपडेट हो जाएगा। तो, इस तरह की एक मॉडल के साथ:)

class Model_OpenStat extends RedBean_SimpleModel{ 
    function update(){ 
    $sql = 'SELECT * FROM `open_stat` WHERE `delivery_id`=? AND 'subscriber_id'=? LIMIT 1 FOR UPDATE'; 
    $args = array($this->bean->deliver_id, $this->bean->subscriber_id); 
    $dupRow = R::getRow($sql, $args); 
    if(is_array($dupRow) && isset($dupRow['id'])){ 
     foreach($this->bean->getProperties() as $property => $value){ 
      #set your criteria here for which fields 
      #should be from the one in the database and which should come from this copy 
      #this version simply takes all unset values in the current and sets them 
      #from the one in the database 
      if(!isset($value) && isset($dupRow[$property])) 
      $this->bean->$property = $dupRow[$property]; 
     } 
     $this->bean->id = $dupId['id']; #set id to the duplicates id 
    } 
    return true; 
    } 
} 

फिर आप आर संशोधित करेगा :: दुकान (ताकि तरह फोन:

\R::begin(); 
\R::store($oOpenStatBean); 
\R::commit(); 

या

\R::transaction(function() use ($oOpenStatBean){ R::store($oOpenStatBean); }); 

लेन-देन का कारण होगा "अद्यतन के लिए" खंड को मिली पंक्ति को लॉक करने के लिए या, उस स्थिति में जहां कोई पंक्ति नहीं मिली थी, उस सूचकांक में स्थानों को लॉक करने के लिए जहां आपकी नई पंक्ति जायेगी ताकि आपके पास समवर्ती समस्याएं न हों।

अब यह रिकॉर्ड के किसी उपयोगकर्ता के अपडेट को हल नहीं करेगा, लेकिन यह एक अलग विषय है।

+0

यह एकीकृत ओआरएम समर्थन जैसे बहुत ही सुरुचिपूर्ण समाधान नहीं है। –

+0

नहीं, दुर्भाग्यवश, उद्धृत चर्चा के अनुसार, सच्ची अपरिपक्व कार्यक्षमता को व्यवसाय तर्क माना जाता था और इसे रेडबीन कोर में एकीकृत नहीं किया गया था। हालांकि, आप अपना खुद का कस्टम क्वेरी लेखक या प्लगइन लिख सकते हैं जो इस तरह की चीज़ को ओआरएम में ले जायेगा। इन्हें लिखने के बारे में जानकारी [दस्तावेज़ीकरण] में है (http://www.redbeanphp.com/plugins/create_your_own) –

+0

धन्यवाद, लेकिन मैंने एक साल पहले यह पूछा था। –

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

  • कोई संबंधित समस्या नहीं^_^