ในโครงการ 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 }