我们有一个现有的SQL数据库,我正在编写一个使用直接SQL访问它的node.js服务器,使用这个postgres驱动程序模块:
https://github.com/brianc/node-postgres
到目前为止,我找不到与postgres一起使用的事务管理节点模块。有谁知道吗?最好是在某些现实世界中使用?
其次,在更高级别,我们正在评估node.js是否可以实际取代Java作为可能处理卷的服务器的真实解决方案。交易管理是我们必须解决的问题之一。因此,对此的一些见解也很有用。
目前,我只是在节点服务器请求开始时发出一个sql BEGIN,在结尾处发出一个ROLLBACK或COMMIT。但是,我(可能显然)不熟悉围绕SQL事务管理的现实问题。如果有人可以简要解释交易管理框架解决的问题,我会发现它很有用。
编辑:我正在使用postgres驱动程序的内置连接池机制,http请求中的所有查询都是在从池中获取的同一连接上发出的。首先发布BEGIN,然后是特定的http请求,然后是COMMIT或ROLLBACK。
感谢。
答案 0 :(得分:3)
交易管理是一个非常大的主题。对于我的想象,你会想要使用AUTOCOMMIT模式。这基本上意味着你将依赖PostgreSQL来对所有语句进行BEGIN / COMMIT(换句话说,你的所有语句都将在自己的事务中运行而彼此无关)。确定AUTOCOMMIT模式适合您的简单方法是决定您不需要使用ROLLBACK。 AUTOCOMMIT模式的一个巨大好处是即使是最愚蠢的连接池工具也无法搞砸。
关于交易管理的细节,首先看看http://www.postgresql.org/docs/9.1/static/transaction-iso.html你做了什么,确保你没有使用或写一个让你进入的天真框架。在交易"土地。最后,既然你提到了#34;高容量",我应该问一下你的读写均衡是什么。如果它非常支持读取行为,那么您应该考虑编写代码以使用memcached。最简单(但最有效)的方法是使用PQC。
答案 1 :(得分:3)
pg-promise库可以很好地处理事务管理:
db.tx(t => {
return t.batch([
t.query('UPDATE users SET active = $1 WHERE id = $2', [true, 123]),
t.query('INSERT INTO audit(event, id) VALUES($1, $2)', ['activate', 123])
]);
})
.then(data => {
// success;
})
.catch(error => {
// error;
});
答案 2 :(得分:0)
寻找Sequelize http://docs.sequelizejs.com/en/latest/api/transaction/
开始交易时可能使用的隔离级别:
{
READ_UNCOMMITTED: "READ UNCOMMITTED",
READ_COMMITTED: "READ COMMITTED",
REPEATABLE_READ: "REPEATABLE READ",
SERIALIZABLE: "SERIALIZABLE"
}
作为第一个参数传递所需的级别:
return sequelize.transaction({
isolationLevel: Sequelize.Transaction.SERIALIZABLE
}, function (t) {
// your transactions
}).then(function(result) {
// transaction has been committed. Do something after the commit if required.
}).catch(function(err) {
// do something with the err.
});
答案 3 :(得分:0)
我更喜欢使用纯 pg
库,因为它已经具备了交易所需的一切。
这是我的 TypeScript 示例:
import { PoolClient } from "pg"
import { pool } from "../database"
const tx = async (callback: (client: PoolClient) => void) => {
const client = await pool.connect();
try {
await client.query('BEGIN')
try {
await callback(client)
await client.query('COMMIT')
} catch (e) {
await client.query('ROLLBACK')
}
} finally {
client.release()
}
}
export { tx }
用法:
let result;
await tx(async client => {
const { rows } = await client.query<{ cnt: string }>('SELECT COUNT(*) AS cnt FROM users WHERE username = $1', [username]);
result = parseInt(rows[0].cnt) > 0;
});