TP框架 中 union 无法分页 报错SQLSTATE[HY000]: General error: 1221 Incorrect usage of UNION and LIMIT

本文讲述了如何在使用ThinkPHP的ORM进行多表联合查询时,避免SQLSTATE[HY000]:General error: 1221 Incorrect usage of UNION and LIMIT的问题。通过拆分查询条件并结合buildSql()方法,成功实现了跨表数据获取并实现了分页功能。
        $data['list']=Db::field('name')
            ->table('table1')
            ->union(function($query){
                $query->field('name')->table('table2');
            })
            ->union(function($query){
                $query->field('name')->table('table3');
            //->page($p, $pagesize)///////会报错//////
            ->select();

     报错:SQLSTATE[HY000]: General error: 1221 Incorrect usage of UNION and LIMIT

//////////////////////////////以下是解决办法////////////////////////////////////////
 $list1 = Db::field('name')->table('table1')->where($where1)->buildSql();
 $list2 = Db::field('name')->table('table2')->where($where2)->buildSql();
 $list3 = Db::field('name')->table('table3')->where($where3)->union([$list1,$list2,$list3])->buildSql();
        $data['list'] = Db::table( $list3.' a')
            ->field('name')
            ->page($p, $pagesize)
            ->select();

这个错误信息 `SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction` 表示在执行数据库事务时,等待锁的时间超过了 MySQL 的锁等待超时时间(`innodb_lock_wait_timeout`),导致事务被回滚。 ### 常见原因: 1. **事务长时间未提交**:某个事务持有锁的时间太长,导致其他事务等待超时。 2. **死锁或资源竞争**:多个事务相互等待对方释放锁,或者并发访问同一资源。 3. **长查询或大事务**:处理大量数据或执行复杂操作的事务占用资源时间过长。 ### 解决方法: 1. **优化 SQL 查询**: - 避免在事务中执行耗时操作。 - 确保查询使用了合适的索引。 2. **减少事务范围**: - 尽量缩短事务的生命周期,尽早提交或回滚事务。 3. **调整锁等待超时时间**: ```sql SET innodb_lock_wait_timeout = 120; -- 将超时时间调整为120秒 ``` 4. **检查死锁日志**: - 使用 `SHOW ENGINE INNODB STATUS` 查看最近的死锁信息,分析并优化事务逻辑。 5. **避免高并发冲突**: - 通过队列、锁机制或业务逻辑设计来减少并发冲突。 ### 示例代码(调整锁等待超时): ```php // 在执行事务前设置锁等待超时时间 $pdo->exec("SET innodb_lock_wait_timeout = 120"); ``` ### 示例代码(优化事务提交): ```php try { $pdo->beginTransaction(); // 执行一些快速操作 $pdo->exec("UPDATE users SET balance = balance - 100 WHERE id = 1"); $pdo->exec("UPDATE users SET balance = balance + 100 WHERE id = 2"); $pdo->commit(); // 尽快提交事务 } catch (Exception $e) { $pdo->rollBack(); echo "Transaction failed: " . $e->getMessage(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值