Dart 连接 MySQL 后需要延迟 3ms 才能成功查询。为什么?

问题描述 投票:0回答:1

Stack Overflow 社区您好!

我在 Dart 中使用 MySQL 时遇到了一个特殊问题。当我尝试在建立连接后立即查询数据库时,得到空结果。但是,如果我在进行查询之前添加 3 毫秒的延迟,一切都会按预期进行。

这是我的代码片段:

import 'package:mysql1/mysql1.dart';
import 'dart:async';

Future<void> main() async {
  final settings = ConnectionSettings(
    host: '127.0.0.1',
    port: 3306,
    user: 'root',
    password: 'root',
    db: 'base_mysql',
  );

  try {
    final MySqlConnection connection = await MySqlConnection.connect(settings);
    
    // Introducing a short delay before querying
    await Future.delayed(const Duration(milliseconds: 3));
    
    final results = await connection.query('SHOW TABLES');
    for (var row in results) {
      final tableName = row.values?.first;
      if (tableName != null) {
        print('Table Name: $tableName');
      }
    }

    await connection.close();

  } catch (e) {
    print('Error: $e');
  }
}

如果没有这 3 毫秒的延迟,第一个查询将返回空结果。此过程中的 MySQL 日志显示:

2023-10-02T10:24:48.514849Z    43 Connect   root@[client-ip] on base_mysql using TCP/IP
2023-10-02T10:24:48.519878Z    43 Query SHOW TABLES
2023-10-02T10:24:48.539763Z    43 Quit  

我很好奇为什么会发生这种情况。有人遇到过类似的问题吗?我希望对此行为有任何见解或解释。

mysql dart async-await database-connection
1个回答
0
投票

我们使用以下解决方案。
如果发生错误,它可以重置连接并创建一个新连接。
这些网站几个月来一直毫无问题地运行。

import 'dart:async';

import 'package:mysql1/mysql1.dart';

import 'yaml_config.dart';

Completer<MySqlConnection>? _connectionCompleter;

Future<MySqlConnection> getConnection() async {
  try {
    if (_connectionCompleter == null) {
      return _createConnection();
    } else {
      final connection = await _connectionCompleter!.future;
      await connection.query('SELECT 1');
      return connection;
    }
  } catch (e) {
    const knownMessages = [
      'Cannot write to socket, it is closed',
      'Socket has been closed',
    ];
    final message = '$e';
    for (final knownMessage in knownMessages) {
      if (message.contains(knownMessage)) {
        return _createConnection();
      }
    }

    rethrow;
  }
}

Future<MySqlConnection> _connect() async {
  final config = yamlConfig('config.yaml');
  final settings = ConnectionSettings(
      host: config.read('database.host'),
      port: config.read('database.port'),
      user: config.read('database.user'),
      password: config.read('database.password'),
      db: config.read('database.database'));
  final result = await MySqlConnection.connect(settings);
  return result;
}

Future<MySqlConnection> _createConnection() async {
  final completer = Completer<MySqlConnection>();
  _connectionCompleter = completer;
  try {
    final connection = await _connect();
    completer.complete(connection);
  } catch (e, s) {
    completer.completeError(e, s);
    _connectionCompleter = null;
    rethrow;
  }

  return completer.future;
}

© www.soinside.com 2019 - 2024. All rights reserved.