英文:
Serverless Framework + Neo4j
问题
我在使用Serverless Framework连接和断开连接到我的Neo4j数据库时遇到了问题。在Neo4j文档中,JS部分显示了以下代码:
const neo4j = require('neo4j-driver')
const driver = neo4j.driver(uri, neo4j.auth.basic(user, password))
const session = driver.session()
const personName = 'Alice';
try {
const result = await session.run(
'CREATE (a:Person {name: $name}) RETURN a',
{ name: personName }
)
const singleRecord = result.records[0]
const node = singleRecord.get(0)
console.log(node.properties.name)
} finally {
await session.close()
}
// 在应用程序退出时:
await driver.close()
我遇到了这段代码的问题,原因有几个。在我的Lambda函数中,如果只运行这段代码,我会得到以下错误:
Pool is closed, it is no more able to serve requests
如果我将 driver.close
移动到 finally
块中,我会得到以下错误:
Neo4jError: Cannot begin a transaction on a closed session.
明确一下,我可以成功向数据库发出一次请求,然后第二次会失败。
在使用Postgres + Serverless时,我也遇到了这个问题,我通过使用serverless-postgres npm包来解决了这个问题。
似乎我可能不需要使用驱动程序,而是像这里的文档中所示,进行简单的HTTP请求。对于如何继续前进,我对此很感兴趣。
英文:
I'm running into issues with connection and disconnecting to my Neo4j database using the Serverless Framework. In the Neo4j docs, it shows this code in the JS section:
const neo4j = require('neo4j-driver')
const driver = neo4j.driver(uri, neo4j.auth.basic(user, password))
const session = driver.session()
const personName = 'Alice'
try {
const result = await session.run(
'CREATE (a:Person {name: $name}) RETURN a',
{ name: personName }
)
const singleRecord = result.records[0]
const node = singleRecord.get(0)
console.log(node.properties.name)
} finally {
await session.close()
}
// on application exit:
await driver.close()
I run into issues with this code for a couple reasons. In my lambda function, if I run just this code I'll get the error:
Pool is closed, it is no more able to serve requests
If I move the driver.close
into the finally, I'll get this error:
Neo4jError: Cannot begin a transaction on a closed session.
To be clear, I can make one successful request to the database then the second will fail.
I had this issue when using pg-node
with postgres + serverless. I fixed the issue by using the serverless-postgres npm package.
It seems that maybe I need to not use the driver and instead make simple HTTP request like the docs here. Interested in opinions on how to move forward.
答案1
得分: 1
我没有使用Lambda,但我相信对于任何JS运行时都会应用相同的规则。
在下面的示例中,包含了一些驱动程序选项,供您调整并查看哪种组合适用于您的情况。
您可以尝试:
import { driver, auth } from 'neo4j-driver';
import { config } from 'dotenv';
/**
* 读取环境变量(用于测试)
*/
config();
/**
* Neo4j连接驱动程序的单例
*/
const neo4j = driver(process.env.NEO4J_URI, auth.basic(process.env.NEO4J_USER, process.env.NEO4J_PASSWORD),
{
maxConnectionLifetime: 10 * 60 * 1000, // 10分钟
maxConnectionPoolSize: 300,
encrypted: process.env.NEO4J_ENCRYPTION || "ENCRYPTION_ON",
trust: "TRUST_ALL_CERTIFICATES",
// trustedCertificates: [process.env.NEO4J_TRUSTED_CERTS],
logging: {
level: 'debug',
logger: (level, message) => console.log('+++' + level + ' ' + message)
}
});
/**
* 使用池中的会话执行cypher查询的包装器
* 并进行自动事务管理(提交、回滚、会话关闭)
* @param {*} query Cypher语句
* @param {*} params 查询参数
* @returns Promise<Record<Dict, PropertyKey, Dict<PropertyKey, number>>[]>
*/
async function runNeo4jQuery(query, params) {
const session = neo4j.session();
let result;
try {
const transaction = session.beginTransaction();
try {
result = await transaction.run(query, params);
await transaction.commit();
return result.records;
} catch (error) {
await transaction.rollback();
throw error;
}
} finally {
await session.close();
}
}
async function main() {
let results = [];
const statement = `CREATE (a:Person {name: $name}) RETURN a`
let params = {
name: 'Alice'
}
results = await runNeo4jQuery(statement, params);
console.debug(results);
}
(async function () {
await main();
})().catch(e => {
console.error(e);
process.exit(1);
}).finally(async () => {
await neo4j.close();
process.exit(0);
}
注意:上述代码中包含了注释和环境变量的处理,您需要根据您的实际情况进行相应的配置和调整。
英文:
I'm not using Lambda, but I believe for any JS runtime the same rules would apply.
In the example below, included some of the driver's option for you to tweak and see what combination works for your scenario.
Can you try:
import { driver, auth } from 'neo4j-driver';
import { config } from 'dotenv';
/**
* Read environment variables (for test-bed)
*/
config();
/**
* Singleton for Neo4j Connection Driver
*/
const neo4j = driver(process.env.NEO4J_URI, auth.basic(process.env.NEO4J_USER, process.env.NEO4J_PASSWORD),
{
maxConnectionLifetime: 10 * 60 * 1000, // 10 minutes
maxConnectionPoolSize: 300,
encrypted: process.env.NEO4J_ENCRYPTION || "ENCRYPTION_ON",
trust: "TRUST_ALL_CERTIFICATES",
// trustedCertificates: [process.env.NEO4J_TRUSTED_CERTS],
logging: {
level: 'debug',
logger: (level, message) => console.log('+++' + level + ' ' + message)
}
});
/**
* Wrapper to execute cypher queries using session from pool
* and automatic transaction management (commit, rollback, session closing)
* @param {*} query Cypher statement(s)
* @param {*} params Query params
* @returns Promise<Record<Dict, PropertyKey, Dict<PropertyKey, number>>[]>
*/
async function runNeo4jQuery(query, params) {
const session = neo4j.session();
let result;
try {
const transaction = session.beginTransaction();
try {
result = await transaction.run(query, params);
await transaction.commit();
return result.records;
} catch (error) {
await transaction.rollback();
throw error;
}
} finally {
await session.close();
}
}
async function main() {
let results = [];
const statement = `CREATE (a:Person {name: $name}) RETURN a`
let params = {
name: 'Alice'
}
results = await runNeo4jQuery(statement, params);
console.debug(results);
}
(async function () {
await main();
})().catch(e => {
console.error(e);
process.exit(1);
}).finally(async () => {
await neo4j.close();
process.exit(0);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论