symfony2 как гарантировать, что серийный номер не используется

У меня есть система управления документами в symfony2.
Как только пользователь установит мою сущность документа, ему будет присвоен серийный номер.

Вот как я могу найти сериал для назначения
1) Проверьте в БД наивысший серийный номер в использовании
2) Назначить и очистить сущность.

Я использую этот серийный номер в качестве идентификатора для нескольких версий этой сущности, поэтому он не уникален для БД.

Как я могу гарантировать, что назначенный номер действительно уникален? Я бы блокировал таблицы в плоском php, но не знал, как это сделать, или если это лучший метод в symfony2.

/**
* Establishes a analysi entity.
*
*/
public function establishAction(Request $request, Analysis $analysi)
{

...

$analysi->setSerial( $this->getNewSerial() );//set a new serial number
//TODO: How to confirm this is really not in use since there is no transaction locking going on here?
$em->flush($analysi);

...

}private function getNewSerial()
{
$em = $this->getDoctrine()->getManager();

//get highest serial nb from established analysises
$results = $em->createQuery("SELECT MAX(a.serial) FROM HazardlogBundle:Analysis a WHERE a.currentVersion = true")->getResult();
$temp = $results[0];
$max_serial = $temp[1];

$new_serial = $max_serial + 1;

return $new_serial;
}

—————- ОБНОВИТЬ

Я должен явно уточнить:
Я могу иметь…

entity A with serial 123 and version 1
entity B with serial 123 and version 2
entity C with serial 124 and version 1
entity D with serial 125 and version 1

Чего я боюсь, так это того, что пользователи одновременно создают сущность C и D, и поэтому мой контроллер может получить самый высокий на данный момент серийный номер, используемый для создания сущности C, и до того, как сущность C будет сброшена в DB, ​​поток, обслуживающий пользователя, создающего сущность D будет читать наибольшее число 123 из БД до того, как в БД будет записана сущность С с последовательным номером 124. Таким образом, я в конечном итоге с Entity C & Буду оба иметь серийный 124.

Возможно, я мог бы определить уникальный индекс, состоящий из серийного номера и номера версии, чтобы обойти эту проблему?

0

Решение

я думаю, что вы должны поместить логику уникальности в вашу сущность с аннотацией.

SRC / HazardlogBundle / Entity / Analysis.php

    /**
* @var string
*
* @ORM\Column(name="serial", type="integer", unique=true)
*/
private $serial;
0

Другие решения

Если вы используете MySQL — вы можете использовать AUTO_INCREMENT на отдельной таблице. Вы можете найти больше в документации MySQL: http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id, см. часть «Симуляция последовательностей».

Если вы используете PostgreSQL / Oracle / etc, вы можете использовать последовательности: https://www.postgresql.org/docs/9.5/static/functions-sequence.html

Также вы можете использовать uuid4 и сгенерировать его в php. Здесь очень низкий шанс получить дубликат ключа.

Все случаи (кроме mysql one) могут быть закодированы как отдельный код или как доктрина @GeneratedValue, http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#identifier-generation-strategies
MySQL исключен, потому что только один AUTO_INCREMENT на таблицу, и, возможно, вы уже использовали его для первичного ключа.

0

Я нашел способ создать уникальный индекс путем объединения двух столбцов, например:

/**
* Analysis
*
* @ORM\Table(name="analysis",uniqueConstraints={@ORM\UniqueConstraint(name="unique_version_serial", columns={"Version", "serial"})})
* @ORM\Entity(repositoryClass="HazardlogBundle\Repository\AnalysisRepository")
*/
class Analysis

0
По вопросам рекламы [email protected]