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
我很好奇为什么会发生这种情况。有人遇到过类似的问题吗?我希望对此行为有任何见解或解释。
我们使用以下解决方案。
如果发生错误,它可以重置连接并创建一个新连接。
这些网站几个月来一直毫无问题地运行。
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;
}