node.js + postgres数据库事务管理

时间:2012-02-16 21:11:06

标签: sql database postgresql node.js transactions

我们有一个现有的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。

感谢。

4 个答案:

答案 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;
});