php - 通过 Doctrine 连接直接调用 MySQL 函数返回 'cached' 结果

标签 php mysql symfony doctrine

我有一个MySQL函数,用于对提交的文档进行编号。它直接在 MySQL 服务器中实现(几乎可以避免死锁、并发和类似的好事)。表存储特定文档键的最后使用的编号,函数获取该编号,将其递增并返回到 Symfony 应用程序,该应用程序将其分配给文档。

DELIMITER $$
FUNCTION `NEXT_NUMBER`(requested_key VARCHAR(255)) RETURNS int(11)
BEGIN
    DECLARE nextNumber INT;

    INSERT INTO `document_numbers` (key, last_number) VALUES (requested_key, 1)
        ON DUPLICATE KEY UPDATE last_number = last_number+1;
        SELECT last_number INTO nextNumber FROM `document_numbers` WHERE key = requested_key

   RETURN nextNumber;
END$$
DELIMITER ;

在应用程序中,该函数在单独的 Doctrine 连接中调用,不用于标准实体和数据库操作。

public function getNewNumber(string $key) : int
{
    $this->connection->setAutoCommit(false);

    try {
        $this->connection->beginTransaction();
        $statement = $this->connection->prepare("SELECT NEXT_NUMBER(:key);");
        $statement->bindValue('series', $key);
        $statement->execute();
        $this->connection->commit();

        $number = (int) $statement->fetchColumn();

        $this->connection->close();
    } catch (\Throwable $e) {
        $this->connection->rollBack();
        $this->connection->close();
        throw $e;
    }

    return $number;
}

现在有问题的部分是

$number = (int) $statement->fetchColumn();

通过多个 HTTP 请求返回相同的值。行为与缓存结果值几乎相同。此行为不会 100% 重复。我尝试将 SQL_NO_CACHE 添加到 SELECT 查询,但无济于事。

设置:

  • MySQL 5.7
  • Symfony 3.4
  • PHP 7.1
  • Doctrine/DBAL 2.7
  • Oro平台3.1

Doctrine 配置:

doctrine:
    dbal:
        default_connection:   default
        connections:
            default:
                server_version: '5.7'
                driver:       "%database_driver%"
                host:         "%database_host%"
                port:         "%database_port%"
                dbname:       "%database_name%"
                user:         "%database_user%"
                password:     "%database_password%"
                charset:      UTF8MB4
                mapping_types:
                    bit: boolean
                    json: string
            secondary: # this one is used for $this->connection->prepare("SELECT NEXT_NUMBER(:key);");
                server_version: '5.7'
                driver:       "%database_driver%"
                host:         "%database_host_secondary%" # this is simply pointing to 127.0.1.1
                port:         "%database_port%"
                dbname:       "%database_name%"
                user:         "%database_user%"
                password:     "%database_password%"
                charset:      UTF8MB4

不存在 MySQL/Doctrine 缓存设置。

最佳答案

因此,一种解决方案是重新打开自动提交 $this->connection->setAutoCommit(true);,尽管在​​ Symfony 上使用相同的代码时情况绝对不是这样2.8 和之前版本的 Doctrine。

此外,“SELECT NEXT_NUMBER(:key);”实际上返回了递增的数字,而不是某些“缓存”版本,但在递增后没有将其提交到数据库表。

我不知道这是如何发生的,因为 $this->connection->commit(); 已明确执行并且不会引发任何错误。也许 MySQL/PHP/Doctrine 正在以某种方式为操作创建单独的事务。然而,到目前为止,自动提交似乎没有遇到任何问题,因此问题本身可能已经解决,尽管任何对行为的输入和描述都将不胜感激。

关于php - 通过 Doctrine 连接直接调用 MySQL 函数返回 'cached' 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56560488/

相关文章:

php - 在 000webhost 上使用 laravel 时 MySQL 连接被拒绝

mysql - 使用docker compose并使用mariadb 10.4.8 docker容器对用户 'root' @'localhost'的访问被拒绝,并在附加外部卷时发出

php - WHERE 子句在使用 mdbtools 的 SQL 查询中不起作用

c# - 无法按名称或路径删除图像文件

php - 在 session 中添加 ids 作为数组并根据其中的 ids 返回产品

regex - 如何从 Symfony 路由模式正则表达式中排除特定链接?

php - Symfony2 : The CSRF token is invalid. 请尝试重新提交表单

events - symfony 域事件

php - 数据库查询失败 : Incorrect integer value: '' for column 'id' at row 1

php - 无法将 DataGrip 连接到使用 XAMPP 托管的数据库