这是 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()?现在我的数据库连接不能关闭,造成了连接数过高的缘由。谢谢~
使用 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我怎么找不到。用你的例子报错。