node-mysql 事务
发布于 10 年前 作者 songqinghehe 6859 次浏览 最后一次编辑是 8 年前 来自 问答

这是 https://github.com/felixge/node-mysql 的官方用法: connection.beginTransaction(function(err) { if (err) { throw err; } connection.query(‘INSERT INTO posts SET title=?’, title, function(err, result) { if (err) { connection.rollback(function() { throw err; }); }

var log = 'Post ' + result.insertId + ' added';

connection.query('INSERT INTO log SET data=?', log, function(err, result) {
  if (err) { 
    connection.rollback(function() {
      throw err;
    });
  }  
  connection.commit(function(err) {
    if (err) { 
      connection.rollback(function() {
        throw err;
      });
    }
    console.log('success!');
  });
});

}); });

请问下大神们:我在那里执行.end()?现在我的数据库连接不能关闭,造成了连接数过高的缘由。谢谢~

8 回复

使用 pool 会管理好连接数。 var mysql = require(‘mysql’); var pool = mysql.createPool({ connectionLimit : 10, host : ‘example.org’, user : ‘bob’, password : ‘secret’ });

@mrlong我看官方文档没有提供pool版的事务处理。一直不知道该如何解决

@songqinghehe https://www.npmjs.com/package/mysql 明显是有连接池的,建议你用 bluebird 封装一下。以下是参考代码。我用的是 PostgreSQL,默认就有连接池,mysql 看着也差不多,用上连接池,下面的代码改改就OK了。

var pg = require(‘pg’); var bb = require(‘bluebird’); var cs = “YOUR CONNECTION STRING”;

Object.keys(pg).forEach(function(key) { if (key == ‘native’) return; var klass = pg[key]; if (typeof klcass === ‘function’) { bb.promisifyAll(klass.prototype); bb.promisifyAll(klass); } })

bb.longStackTraces(); bb.promisifyAll(pg);

var connect = function(callback) { pg.connectAsync(connectionStr).spread(function(client, release) { var query = client.queryAsync.bind(client); callback(query, release); } }

// 调用示例:

connect(function(query, release) { query(“select id from xxx”, [params1, param2]).then(function(rs) { if (rs.rows[0].length) return rs; // 存在于数据库,直接返回 [值] 一级的 then 会接收到 return query(“insert into xxx returning id”) // 返回一个新的 [promise] 给一级 then }).then(function(rs) { // <— 一级 then return query(“insert into relation_table values($1, $2)”, […, rs.rows[0].id); // 一定要 return 这样 promise 链才会继续,不 return 新的 promise 会导致连接提前释放。 }).finally(release) })

可以参考或者直接使用 ali-rds 这个模块来做 mysql 客户端 https://github.com/ali-sdk/ali-sdk/blob/master/docs/rds.md#transactions

Transactions

  • Get connection first
var conn = yield db.getConnection();
  • beginTransaction, commit or rollback
var conn = yield db.getConnection();
try {
  yield conn.beginTransaction();
} catch (err) {
  conn.release();
  throw err;
}

try {
  yield conn.query(insertSQL1);
  yield conn.query(insertSQL2);
  yield conn.commit();
} catch (err) {
  // error, rollback
  yield conn.rollback(); // rollback call won't throw err
  throw err;
} finally {
  // should release connection whatever
  conn.release();
}

@fengmk2 你这代码写得好像是同步执行。i like it 不是用了 yield ?

@fengmk2 大神,看我这是什么原因 ali-res 我参考了还是找不出原因: https://cnodejs.org/topic/55589dcf7cabb7b45ee6bdaa

@mrlong cal lback我就不管了

@fengmk2 yield我怎么找不到。用你的例子报错。 屏幕快照 2015-05-18 10.57.42.png 屏幕快照 2015-05-18 10.57.59.png

回到顶部