指尖上的记忆指尖上的记忆
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub

symfony7之DataFixtures使用注意事项:

1>一般直接执行 php bin/console doctrine:fixtures:load --append 即可将数据初始化到数据库。一定要加 --append, 除非是第一次拉项目,初始化数据库, 否则操作会清空整个数据库(purging database)中的所有表,而不是仅仅清空与指定 group 相关的表. 这直接会把已经存在的数据清理掉.

2>假如后来在DataFixtures又有了新的fixture的话,我只想执行新添加的怎么办 ①一开始想到的是如下方法 php bin/console doctrine:fixtures:load --fixtures=src/DataFixtures/LoadEventSubmissionFileRequiredOptionsData.php --fixtures=src/DataFixtures/LoadEventSubmissionFiletypesData.php --fixtures=src/DataFixtures/LoadEventSubmissionTypeWorkflowsData.php --fixtures=src/DataFixtures/LoadEventSubmissionWorkflowData.php

但是报: doctrine:fixtures:load [--append] [--group GROUP] [--em EM] [--purger PURGER] [--purge-exclusions PURGE-EXCLUSIONS] [--purge-with-truncate] 也即是没有 --fixtures 选项(说明这个方法是错的,没用)

②使用 group 解决这个问题(真的很实用)

  1. 定义组标签: 首先,DataFixture 类中实现 FixtureGroupInterface,并定义一个组标签。例如:

    <?php
    
    namespace App\DataFixtures;
    
    use Doctrine\Bundle\FixturesBundle\Fixture;
    use Doctrine\Persistence\ObjectManager;
    use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
    
    // 必须要实现这个FixtureGroupInterface
    class UserFixtures extends Fixture implements FixtureGroupInterface
    {
        public function load(ObjectManager $manager): void
        {
            // 定义数据加载逻辑
        }
    
        public static function getGroups(): array
        {
            return ['userGroup'];
        }
    }
    
  2. 加载特定的组: 在执行命令时,可以通过 --group 参数指定要加载的 Fixtures 组:

    php bin/console doctrine:fixtures:load --group=userGroup
    

    如果想同时加载多个组,可以添加多个 --group 参数:

    php bin/console doctrine:fixtures:load --group=userGroup --group=productGroup
    

3>小插曲 当时忘了加 --append, 然后无法直接取消,然后直接关了 terminal, 但是后台的进程肯定还在运行,再次执行加上了 --append, 直接报了下面的错误 An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction

原因分析: 因为你在第一次执行 doctrine:fixtures:load 时没有使用 --append,导致数据库在执行清空操作时被锁定,而你中断了这个进程(关闭了 terminal 对话框)。这会导致事务没有正确结束,造成表被锁定,从而引发了后续的锁等待超时问题 (Lock wait timeout exceeded)。

处理步骤

1. 检查并终止锁定的事务

你可以通过 MySQL 命令来查看和终止未完成的事务:

  • 查看当前的锁定情况: 使用以下命令查看当前被锁定的事务:

    SHOW ENGINE INNODB STATUS;
    

    这个命令会返回详细的 InnoDB 状态信息,帮助你找出哪个事务占用了锁。

  • 终止锁定的事务: 使用 SHOW FULL PROCESSLIST 查找长时间运行的查询,然后使用 KILL QUERY 终止它。

    SHOW FULL PROCESSLIST;
    

    查找到 state 为 Locked 的查询,记下对应的 ID,然后使用以下命令终止该查询:

    KILL QUERY <ID>;
    

2. 重启 MySQL 服务(如有必要)

如果手动终止事务没有效果,或者你不确定哪个事务在持有锁,重启 MySQL 服务会释放所有锁定的事务:

sudo systemctl restart mysql

3. 再次执行 doctrine:fixtures:load 并使用 --append

清除锁定问题后,再次执行 doctrine:fixtures:load,并确保这次使用 --append,以防止数据被清空:

php bin/console doctrine:fixtures:load --group=event_submission --append

这样可以避免再次清空整个数据库,保留已有数据,同时加载指定的 Fixtures。

总结

  • 未正确结束的事务可能会造成数据库锁定,导致后续操作失败。
  • 检查并终止锁定的事务,或者通过重启 MySQL 服务释放锁。
  • 重新运行 doctrine:fixtures:load 时使用 --append,以避免再次触发 purging database 操作。