PHPackages                             sue/async-mysql - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. sue/async-mysql

ActiveLibrary[Database &amp; ORM](/categories/database)

sue/async-mysql
===============

提供基于illuminate/database的组件的mysql异步驱动

1.0.0(2y ago)06MITPHPPHP &gt;=5.6.0

Since Jul 27Pushed 2y ago1 watchersCompare

[ Source](https://github.com/heroest/sue-async-mysql)[ Packagist](https://packagist.org/packages/sue/async-mysql)[ RSS](/packages/sue-async-mysql/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (7)Versions (2)Used By (0)

sue\\async-mysql
================

[](#sueasync-mysql)

提供基于`Illuminate\Database`包的异步执行SQL的组件，具体使用可以参考：[使用手册](https://learnku.com/docs/laravel/8.x/eloquent/9400)

需求
--

[](#需求)

> php &gt;= 5.6.4 ext-pdo ext-mysqli

安装方法
----

[](#安装方法)

```
$ composer require sue/async-mysql
```

强烈推荐配合[sue\\coroutine](https://packagist.org/packages/sue/coroutine)协程组件来避免[回调地狱](https://zhuanlan.zhihu.com/p/326902537)

**内容列表**

- [注意事项](#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9)
- [Quickstart example](#quickstart-example)
- \[使用方式\]
    - [laravel框架](#laravel%E6%A1%86%E6%9E%B6)
    - [其他框架](#%E5%85%B6%E4%BB%96%E6%A1%86%E6%9E%B6)
- \[功能列表\]
    - [数据库事务](#%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1)
    - [读写分离](#%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB)
    - [设置SQL超时时间](#SQL%E8%B6%85%E6%97%B6)
    - [unprepared方法](#unprepared)
    - [连接资源回收](#%E8%BF%9E%E6%8E%A5%E8%B5%84%E6%BA%90%E5%9B%9E%E6%94%B6)
    - [ping](#ping)
- [Tests](#tests)
- [License](#license)

#### 注意事项

[](#注意事项)

- `Illuminate\Database\Eloquent`以及`Illuminate\Database\Migrations`暂时不支持
- 重写了Illuminate\\Database\\Connection类，DB::pretend()方法暂时也无法使用

#### Quickstart example

[](#quickstart-example)

```
use Illuminate\Support\Facades\DB;

use function Sue\EventLoop\loop;
use function Sue\Coroutine\co;

co(function () {
    $connection = DB::connection('async-mysql');
    //以下3条SQL将并行执行
    $users = yield [
        $connection->table('users')->where('name', 'foo')->first(),
        $connection->table('users')->where('name', 'bar')->first(),
        $connection->table('users')->where('name', 'baz')->first()
    ];
    echo $users[0]->name; //expected value is 'foo'
    echo $users[1]->name; //expected value is 'bar'
    echo $users[2]->name; //expected value is 'baz'
});
```

#### laravel框架

[](#laravel框架)

- 在`config/app.php` 中引入service-provider `Sue\Async\Mysql\AsyncMysqlServiceProvider`
- 在`config/database.php`中的`connections`直接复制现有的配置，然后修改driver为`async-mysql`

```
 [
    'driver' => 'async-mysql',
    'write' => [
        'host' => ['localhost1', 'localhost2'],
        'username' => 'root',
        'password' => 'root',
        /** 可选配置
        OptionConst::NUM_CONNECTIONS => 5, //配置链接数为5
        */
    ],
    'read' => [
        'host' => ['localhost1', 'localhost2'],
        'username' => 'root',
        'password' => 'root',
        /** 可选配置
        OptionConst::NUM_CONNECTIONS => 10, //配置连接数为5
        */
    ],
    /**
     * 可选配置
    OptionConst::MAX_RUNNING_SECONDS => 30, //SQL最大运行时间
    OptionConst::IDLE_TIMEOUT => 30, //连接被回收前闲置的最大时间限制
    OptionConst::WAITING_LIST_SIZE => 1000, //待执行SQL的等待列表大小
    **/
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'strict' => true,
    'engine' => null
];
```

- 使用方法

```
use Illuminate\Support\Facades\DB;

use function Sue\EventLoop\loop();

DB::connection('async-mysql')
    ->table('users')
    ->where('username', 'foo')
    ->first()
    ->then(function ($user) {
        echo "User " . $user->username . "\n";
    }, function ($error) {
        echo $error . "\n";
    });
loop()->run();
```

#### 其他框架

[](#其他框架)

- 先在合适的地方添加以下代码， 比方说`index.php`等入口文件

```
$db = new \Illuminate\Database\Capsule\Manager;
$db->addConnection([
    'driver' => 'async-mysql',
    'write' => [
        'host' => ['localhost'],
        'username' => 'root',
        'password' => 'root',
        /** 可选配置
        OptionConst::NUM_CONNECTIONS => 5, //配置链接数为5
        */
    ],
    'read' => [
        'host' => ['localhost'],
        'username' => 'root',
        'password' => 'root',
        /** 可选配置
        OptionConst::NUM_CONNECTIONS => 10, //配置连接数为5
        */
    ],
    /**
     * 可选配置
    OptionConst::MAX_RUNNING_SECONDS => 30, //SQL最大运行时间
    OptionConst::IDLE_TIMEOUT => 30, //连接被回收前闲置的最大时间限制
    OptionConst::WAITING_LIST_SIZE => 1000, //待执行SQL的等待列表大小
    **/
    'port' => 3306,
    'database' => 'main',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'strict' => true,
    'engine' => null
], 'async-mysql');
$manager = $db->getDatabaseManager();
$logger = new PsrLogger(); //这里可以初始化一个 \Psr\Log\LoggerInterface的实例，没有的话传null
$manager->extend('async-mysql', function ($config, $name, $logger) {
    $config['name'] = $name;
    return new Connection($config, $logger);
});
$db->setAsGlobal(); //设置全局可用
```

- 使用方法

```
use Illuminate\Database\Capsule\Manager as DB;
use Sue\EventLoop\loop;

DB::connection('async-mysql')
    ->table('users')
    ->where('username', 'foo')
    ->first()
    ->then(function ($user) {
        echo "User " . $user->username . "\n";
    }, function ($error) {
        echo $error . "\n";
    });
loop()->run();
```

#### 数据库事务

[](#数据库事务)

`sue\async\mysql`由于采用了连接池，数据库事务跟链接绑定，所以要在事务中执行SQL的话需要使用指定的链接 \*\*\* 暂时不支持事务嵌套以及savepoint \*\*\*

```
use function Sue\Coroutine\co;
use function Sue\EventLoop\loop;

co(function () {
    $connection = DB::connection('async-mysql')
    $transaction = yield $connection->beginTransaction();
    try {
        $num_updated = yield $connection->table('users')
            ->setTransaction($transaction)
            ->where('name', 'foo')
            ->update(['age' => 18]);
        $bool = yield $connection->commit($transaction);
    } catch (Exception $e) {
        echo "some error: " .  $e . "\n";
        yield $connection->rollback($transaction);
    }
});

loop()->run();
```

#### 读写分离

[](#读写分离)

`sue/async-mysql`会自行判断使用主库还是从库，也可以使用方法`setUseWrite()`方法来指定强制用主库执行SQL

```
DB::connection('async-mysql')
    ->table('users')
    ->setUseWrite() //强制读主库
    ->where('name', 'foo')
    ->first()
    ->then(function ($user) {
        echo "name: " . $user->name;
    }, function ($error) {
        echo $error;
    });

loop()->run();
```

#### SQL超时

[](#sql超时)

\[SQL超时时间\] = \[SQL执行时间\] + \[等待列表时等待数据库连接分配时间\] 设置SQL执行超时时间有两种方式

- 在`config`中配置全局的SQL最大执行时间

```
use Sue\Async\Mysql\OptionConst;

$config = [
    'async-mysql' => [
        'driver' => 'async-mysql',
        'read' => [],
        'write' => [],
        'port' => 3306,
        OptionConst::MAX_RUNNING_SECONDS => 30, //最多运行30秒
    ]
];
```

- 针对单个SQL设置超时时间

```
use React\Promise\Timer\TimeoutException;

DB::connection('async-mysql')
    ->table('users')
    ->setTimeout(3) //超时时间3秒
    ->selectRaw('SLEEP(5)') //让mysql sleep5秒后再返回结果
    ->first()
    ->then(function ($user) {
        //wont be here
    }, function (TimeoutException $e) {
        echo "timeout exception";
    });
```

#### unprepared

[](#unprepared)

`unprepared()`方法现在接受一个额外参数`QueryOption`, 可以设置`超时时间` / `主从配置` / `数据库事务`配置

```
use Sue\Async\Mysql\Query\QueryOption;

use function Sue\EventLoop\loop;
use function Sue\Coroutine\co;

//设置超时时间
$option = new QueryOption();
$option->setTimeout(2); //设置SQL 2秒超时
DB::connection('async-mysql')->unprepared("select * from users", $option);

//设置强制读主
$option = new QueryOption();
$option->setUseWrite();
DB::connection('async-mysql')->unprepared("select * from users", $option);

//设置事务
co(function () {
    $connection = DB::connection('async-mysql');
    $transaction = yield $connection->startTransaction();
    $option = new QueryOption();
    $option->setTransaction($transaction);
    $connection->unprepared("select * from users", $option);
    yield $connection->commit($transaction);
});

loop()->run();
```

#### 连接资源回收

[](#连接资源回收)

`async-mysql`默认不回收资源，原因如下

- php-fpm方式中没必要
- 在常驻进程中加定时器可能导致`loop()->run()`无法自动退出
- 如有需要可以用以下方式手动开启

```
$connection = DB::connection('async-mysql');
$seconds_delay = 3;
$connection->setPipeRecycleDebounceSeconds($seconds_delay);
//SQL完成后防抖3秒后尝试回收闲置时间超过IDLE_TIMEOUT的处于idle状态的连接
```

#### ping

[](#ping)

`async-mysql`默认不开启ping功能，原因跟[连接资源回收](#%E8%BF%9E%E6%8E%A5%E8%B5%84%E6%BA%90%E5%9B%9E%E6%94%B6)一致，如有需要可以手动开启

```
$connection = DB::connection('async-mysql');
$seconds_delay = 3;
$connection->setPipePingDebounceSeconds($seconds_delay);
//SQL请求时防抖3秒后尝试ping所有非关闭的连接，如果ping失败的话会尝试关闭处于idle状态的连接
```

#### tests

[](#tests)

- 先拉取项目

```
$ git clone http://gitlab.sue.com/PHP_Component/async-mysql.git
```

- 然后再phpunit.xml.dist里配置数据库连接

```

```

- 最后执行单元测试

```
$ ./vendor/bin/testbench package:test
```

#### License

[](#license)

The MIT License (MIT)

Copyright (c) 2023 Donghai Zhang

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1025d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3ff9237d92e6d159fa3abb5d711b90c808629e58ec856221c377b37a20d279de?d=identicon)[heroest](/maintainers/heroest)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/sue-async-mysql/health.svg)

```
[![Health](https://phpackages.com/badges/sue-async-mysql/health.svg)](https://phpackages.com/packages/sue-async-mysql)
```

###  Alternatives

[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[staudenmeir/eloquent-json-relations

Laravel Eloquent relationships with JSON keys

1.1k5.8M24](/packages/staudenmeir-eloquent-json-relations)[bavix/laravel-wallet

It's easy to work with a virtual wallet.

1.3k1.1M11](/packages/bavix-laravel-wallet)[staudenmeir/laravel-migration-views

Laravel database migrations with SQL views

2161.7M12](/packages/staudenmeir-laravel-migration-views)[dragon-code/migrate-db

Easy data transfer from one database to another

15717.4k](/packages/dragon-code-migrate-db)[rodrigopedra/laravel-query-logger

Laravel query logger

1211.8k](/packages/rodrigopedra-laravel-query-logger)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
