لا يجلب اسئلة webpocket php أحدث البيانات من العقيدة

0

حقيقة رائعة حقًا اكتشفتها للتو أثناء العبث بتطبيق WebSocket الذي أقوم به حاليًا باستخدام Symfony 4.1 و https://github.com/GeniusesOfSymfony/WebSocketBundle (الذي يعتمد على PHP Ratchet).

كنت أرغب في جلب أحدث البيانات بشكل دوري من قاعدة بيانات MySQL لغرض الاختبار باستخدام $repository->find(2); لكنها دائمًا ما أعادت نفس النتيجة على الرغم من أنني كنت أغير البيانات أثناء الاشتراك في قناة WebSocket.

بعد ساعات طويلة من العبث بالشفرة والبكاء ، اكتشفت أن العقيدة لسبب ما هي نتائج التخزين المؤقت (أو هذا ما أعتقد أنه يفعله).

لاختبار نظريتي ، أنشأت خدمة تتعامل مع الجلب من قاعدة البيانات باستخدام الرمز التالي:

/**
 * @return mixed
 * @throws \Doctrine\DBAL\DBALException
 */
public function fetchNewest()
{
    $stmt = $this->em->getConnection()->prepare('SELECT * FROM test WHERE id=2');
    $stmt->execute();

    return $stmt->fetch();
}

ولسبب ما ، نجح ذلك. يمكن لأي شخص أن يشرح لماذا find(2) لم ينتج عن الطريقة أحدث البيانات بينما فعلت SQL الخام؟

2 الاجابة

2
افضل جواب

هذا هو الصحيح ، والسلوك المتوقع من قبل ORM. هذه طريقة لتخفيف الحمل على قاعدة البيانات.

إنه موثق جيدًا ، ولكن في معظم الأحيان نتخطى الأمثلة ونفقدها. :)

عادةً لن تلاحظ ذلك في أحد التطبيقات ، نظرًا لدورة حياة PHP. يأتي الطلب ، ويخرج الرد ، ويتم إيقاف كل شيء. يبدأ الطلب التالي بصفحة نظيفة.

إذا كنت تستخدم websocket ، فهذا لا يحدث أبدًا ، ف PHP يعمل فقط إلى الأبد (ليس في الحقيقة ، ولكن بشكل مثالي) ، ويستجيب السقاطة للأحداث.

(OFF: تحقق من PHP-PM ... لقد تمكنوا من الوصول إلى زيادة كبيرة في الطلب / الطلبات لأنهم أفسدوا دورة حياة PHP).

يعد وضع القفل حلاً ، ولكن يمكنك أيضًا الاتصال به $em->refresh($entity) ، مما يؤدي إلى إعادة التحميل من ديسيبل.

تحرير: مستندات https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#entities-and-the-identity-map

:مؤلف
0

تمكنت بالفعل من معرفة ذلك بنفسي.

مدير كيان العقيدة find(...) في الواقع الطريقة تخزن النتيجة داخل حقل خاص يسمى $unitOfWork تحت اسم الكيان ومعرف الإدخال.

في كل مرة تحاول العثور على شيء باستخدام $em->find(...) ونجحت النتيجة في الداخل $this->unitOfWork وإذا حاولت جلب نفس الشيء مرة أخرى يتم تحميله فقط من ذاكرة التخزين المؤقت.

   // Check identity map first
    if (($entity = $unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
        if ( ! ($entity instanceof $class->name)) {
            return null;
        }

        switch (true) {
            case LockMode::OPTIMISTIC === $lockMode:
                $this->lock($entity, $lockMode, $lockVersion);
                break;

            case LockMode::NONE === $lockMode:
            case LockMode::PESSIMISTIC_READ === $lockMode:
            case LockMode::PESSIMISTIC_WRITE === $lockMode:
                $persister = $unitOfWork->getEntityPersister($class->name);
                $persister->refresh($sortedId, $entity, $lockMode);
                break;
        }

        return $entity; // Hit!
    }

هذه هي حالة "symfony/orm-pack": "^1.0" و "doctrine/orm": "^2.5.11"

تعديل:

جارٍ الاتصال $repository->find(2, LockMode::NONE); يحل المشكلة.

:مؤلف

أسئلة ذات صلة

فوق
قائمة طعام