ในโครงการ drupal 9 ที่แยกส่วนทั้งหมดฉันมีประเภทเอนทิตีที่กำหนดเองและเพิ่มข้อ จำกัด เฉพาะสำหรับหลาย ๆ ฟิลด์ตามที่อธิบายไว้  ที่นี่. วิธีนี้ใช้งานได้ดีและไม่สามารถเพิ่มเอนทิตีที่สองที่มีค่าฟิลด์เดียวกันได้ อย่างไรก็ตาม ฉันใช้คำขอ JSONAPI POST เพื่อสร้างเอนทิตี ฉันสังเกตเห็นว่าเมื่อออกคำขอ POST หลายรายการด้วยค่าฟิลด์เดียวกันที่ตรงกันหลังจากนั้น วิธีการตรวจสอบความถูกต้อง (โดยใช้ไฟล์ entityTypeManager->getStorage(...)->getQuery(...)->เงื่อนไข(...)->ดำเนินการ() เพื่อตรวจสอบฐานข้อมูล) ไม่ส่งคืนเอนทิตีอื่นเนื่องจากยังไม่มีเอนทิตีที่ซ้ำกัน เช่น. มันเกิดขึ้นอย่างรวดเร็วจนมีการสร้างเอนทิตีที่มีค่าเหมือนกันหลายรายการในเวลาประทับเวลาเดียวกัน (The สร้าง ค่าของเอนทิตีเหมือนกัน)!
การข้ามข้อจำกัดเป็นสิ่งที่อันตรายและต้องป้องกัน
ฉันจะทำอย่างไรเพื่อแก้ปัญหานี้
อัปเดต
นี่คือฟังก์ชันที่ถูกเรียกใช้ภายใน ConstraintValidator
ตรวจสอบฟังก์ชั่นสาธารณะ ($ เอนทิตี, ข้อ จำกัด $ ข้อ จำกัด )
{
  ...
  ถ้า (!$this->isUnique($entity))
    $this->context->addViolation($constraint->notUnique);
  ...
}
ฟังก์ชันส่วนตัว isUnique (CustomType $entity) {
  $date = $entity->get('date')->value;
  $type = $entity->bundle();
  $employee = $entity->get('employee')->target_id;
  $query = $this->entityTypeManager->getStorage('custom_type')->getQuery()
    ->เงื่อนไข ('สถานะ', 1)
    ->เงื่อนไข('ประเภท', $ประเภท)
    ->condition('พนักงาน', $employee)
    ->condition('วันที่', $date);
  ถ้า (!is_null($entity->id()))
    $query->condition('id', $entity->id(), '<>');
  $workIds = $query->execute();
  ส่งคืนค่าว่าง ($workIds);
}
ฉันยินดีที่จะพบข้อบกพร่องใด ๆ จนถึงตอนนี้รหัสนี้ใช้ได้ดีในกรณีอื่นๆ ทั้งหมด
อัปเดต Drupal::lock()
ฉันใช้สมาชิกกิจกรรม 2 รายเพื่อเพิ่มและเผยแพร่ \Drupal::ล็อค() ตามที่กล่าวไว้ในความคิดเห็น การใช้ xdebug ฉันสามารถยืนยันได้ว่ามีการเรียกใช้โค้ด อย่างไรก็ตาม การล็อกดูเหมือนจะไม่มีผลใดๆ เอกสารสำหรับ ล็อค() ค่อนข้างจำกัด ไม่แน่ใจว่ามีอะไรผิดปกติที่นี่
<?php
เนมสเปซ Drupal\custom_entities\EventSubscriber;
ใช้ Symfony\Component\EventDispatcher\EventSubscriberInterface;
ใช้ Symfony\Component\HttpKernel\Event\RequestEvent;
ใช้ Symfony\Component\HttpKernel\KernelEvents
คลาส JsonApiRequestDBlock ใช้ EventSubscriberInterface {
  /**
   * เพิ่มการล็อกสำหรับคำขอ JSON:API
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   * เหตุการณ์ที่ต้องดำเนินการ
   */
  ฟังก์ชั่นสาธารณะ onRequest (RequestEvent $event) {
    $request = $event->getRequest();
    ถ้า ($request->getRequestFormat() !== 'api_json') {
      กลับ;
    }
    ถ้า ($request->attributes->get('_route') === 'jsonapi.custom_type--work.collection.post' &&
      $request->attributes->get('_controller') === 'jsonapi.entity_resource:createIndividual'
    ) {
      $lock = \Drupal::lock();
      $lock->acquire('custom_create_lock');
    }
  }
  /**
   * {@inheritdoc}
   */
  ฟังก์ชั่นคงที่สาธารณะ getSubscribedEvents () {
    $events[KernelEvents::REQUEST][] = ['onRequest'];
    ส่งคืนเหตุการณ์ $;
  }
}
และปลดล็อคหลังจากการตอบสนอง
<?php
เนมสเปซ Drupal\custom_entities\EventSubscriber;
ใช้ Symfony\Component\EventDispatcher\EventSubscriberInterface;
ใช้ Symfony\Component\HttpKernel\Event\ResponseEvent;
ใช้ Symfony\Component\HttpKernel\KernelEvents
คลาส JsonApiResponseDBRelease ใช้ EventSubscriberInterface {
  /**
   * {@inheritdoc}
   */
  ฟังก์ชั่นคงที่สาธารณะ getSubscribedEvents () {
    $events[KernelEvents::RESPONSE][] = ['onResponse'];
    ส่งคืนเหตุการณ์ $;
  }
  /**
   * รีลีสการตอบสนอง JSON:API
   *
   * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event
   * เหตุการณ์ที่ต้องดำเนินการ
   */
  ฟังก์ชั่นสาธารณะ onResponse (ResponseEvent $event) {
    $response = $event->getResponse();
    ถ้า (strpos($response->headers->get('Content-Type'), 'application/vnd.api+json') === FALSE) {
      กลับ;
    }
    $request = $event->getRequest();
    ถ้า ($request->attributes->get('_route') === 'jsonapi.custom_type--work.collection.post' &&
      $request->attributes->get('_controller') === 'jsonapi.entity_resource:createIndividual'
    ) {
      // ปลดล็อค
      $lock = \Drupal::lock();
      ถ้า (!$lock->lockMayBeAvailable('custom_create_lock'))
        $lock->release('custom_create_lock');
    }
  }
}
นี้ถูกเพิ่มเข้าไปใน บริการ.yml
  # สมาชิกกิจกรรม
  custom_entities.jsonapi_db_lock.subscriber:
    คลาส: Drupal\custom_entities\EventSubscriber\JsonApiRequestDBlock
    แท็ก:
      - { ชื่อ: event_subscriber }
  custom_entities.jsonapi_response_db_release.subscriber:
    คลาส: Drupal\custom_entities\EventSubscriber\JsonApiResponseDBRelease
    แท็ก:
      - { ชื่อ: event_subscriber }