CNode

node-mysql 事务

问答
Ssongqinghehe发布于11 年前最后回复11 年前8 回复7454 浏览0 收藏

这是 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)

M
mrlong#1·11 年前
M
mrlong#2·11 年前

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

S
songqinghehe#3·11 年前
引用 mrlong使用 pool 会管理好连接数。 var mysql = require('mysql'); var pool = mysql.createPool({ connectionLimit : 1...

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

K
klesh#4·11 年前
引用 songqinghehe@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) })

F
fengmk2#5·11 年前

可以参考或者直接使用 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();
}
M
mrlong#8·11 年前
引用 fengmk2@mrlong cal lback我就不管了

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

参与回复
登录后即可参与回复。登录