我在Dart中创建了一个后端服务器应用程序,它使用MySQL数据库来存储数据。要使用SqlJocky中的ConnectionPool进行SQL调用。
应用程序启动时的操作:
在本地,这种方法工作正常。现在我将开发版本推送到Heroku,几分钟后我就会遇到连接问题。
所以我想知道,我是否需要从用于执行查询的池中关闭/释放单个连接?或者是在查询再次放入池中并可以免费使用后的连接?
所有MySQL商店的抽象基类:
abstract class MySQLStore {
MySQLStore(ConnectionPool connectionPool) {
this._connectionPool = connectionPool;
}
ConnectionPool get connectionPool => this._connectionPool;
ConnectionPool _connectionPool;
}
getAll方法的具体实现:
Future<List<T>> getAll() async {
Completer completer = new Completer();
connectionPool.query("SELECT id, name, description FROM role").then((result) {
return result.toList();
}).then((rows) {
completer.complete(this._processRows(rows));
}).catchError((error) {
// TODO: Better error handling.
print(error);
completer.complete(null);
});
return completer.future;
}
我得到的错误:
SocketException:操作系统错误:连接超时,errno = 110,地址= ...
答案 0 :(得分:1)
这并没有完全回答您的问题,但我认为您可以简化代码,如:
Future<List<T>> getAll() async {
try {
var result = await connectionPool.query(
"SELECT id, name, description FROM role");
return this._processRows(await result.toList());
} catch(error) {
// TODO: Better error handling.
print(error);
return null;
}
}
我确定无需关闭与query
的连接。我虽然不知道prepareExecute
根据SqlJocky代码中的注释,数据库服务器可能需要相当长的时间才能释放连接。
也许您需要增加连接池大小(默认值为5),以便在ConnectionPool
等待连接释放时不会耗尽连接。
答案 1 :(得分:1)
在Heroku的一些反馈之后,我设法通过实现一个每50秒执行一次基本MySQL调用的计时器任务来解决这个问题。
Heroku的回应:
Heroku的网络强制执行60-90秒的空闲超时以防止失控进程。如果您在应用程序中使用持久连接,请确保在55秒内发送保持活动状态,以防止服务器丢弃您的打开连接。
围绕代码的工作:
const duration = const Duration(seconds: 50);
new Timer.periodic(duration, (Timer t) {
// Do a simple MySQL call with on the connection pool.
this.connectionPool.execute('SELECT id from role');
print('*** Keep alive triggered for MySQL heroku ***');
});