首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >nodejs中的MySQL隔离级别。连接中的每个查询是孤立的还是每个池是孤立的?

nodejs中的MySQL隔离级别。连接中的每个查询是孤立的还是每个池是孤立的?
EN

Stack Overflow用户
提问于 2018-02-25 02:48:59
回答 1查看 1.4K关注 0票数 0

我当前对MySQL的隔离级别是每个会话的tx_transaction = REPEATABLE-READ

因此,当我在不同的终端中运行下面的代码时,事务是串行执行的,这意味着在提交第一个事务之前,第二个事务不会启动。

代码语言:javascript
复制
START TRANSACTION;
SELECT *
FROM test
WHERE id = 4 FOR UPDATE;
UPDATE test
SET parent = 98
WHERE id = 4;

因此,如果我在nodeJS中实现了这一点,那么下面哪个结果与运行两个终端相同?

代码语言:javascript
复制
var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret',
  database : 'my_db'
});

connection.connect();

let query = 
    START TRANSACTION;
    SELECT *
    FROM test
    WHERE id = 4 FOR UPDATE;
    UPDATE test
    SET parent = 98
    WHERE id = 4;

connection.query(query, function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
});

connection.query(query, function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
});

connection.end();

或使用池

代码语言:javascript
复制
var mysql = require('mysql');
var pool  = mysql.createPool({
  connectionLimit : 10,
  host            : 'example.org',
  user            : 'bob',
  password        : 'secret',
  database        : 'my_db'
});

let query = 
    START TRANSACTION;
    SELECT *
    FROM test
    WHERE id = 4 FOR UPDATE;
    UPDATE test
    SET parent = 98
    WHERE id = 4;

pool.query(query, function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
  connection.release();
});

pool.query(query, function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
  connection.release();
});

我最初的猜测是,池将创建单独的连接,在同一个连接中发送查询将与在同一终端中键入查询相同。然而,文档中说的https://github.com/mysqljs/mysql#pooling-connections在导言部分,

在连接上调用的每个方法都按顺序排队和执行。

我不太清楚那是什么意思。

另外,如果我使用连接池,我是否可以100%地确保并发运行的查询由不同的会话处理?因此,例如,如果第一个查询中没有释放池,那么第二个查询是否总是由另一个会话执行?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-15 06:17:11

我做了一些测试,并意识到Connection Pooling的结果符合预期的结果。

当我只使用连接执行以下操作时

代码语言:javascript
复制
let pool = mysql.createConnection({
    connectionLimit:10,
    host: 'localhost',
    user: 'root',
    password: 'thflqkek12!',
    database: 'donationether'
});

connection.beginTransaction(function (err) {
    console.log('first transaction has started');

    if (err) {
        console.log(err);
        return;
    }

    connection.query(`INSERT INTO users VALUES (null, 0, 'username', 'token')`, function (err, results, fields) {
        if (err) {
            console.log(err);
            return;
        }

        setTimeout(function () {
            connection.commit(function (err) {
                if (err) {
                    console.log(err);
                    return;
                }

                console.log('first query done');
                connection.release();
            })
        }, 2000)
    });
});

connection.beginTransaction(function (err) {

    console.log('second transaction has started');

    if(err) {
        console.log(err);
        return;
    }

    connection.query(`UPDATE users SET username = 'c_username' WHERE username = 'username'`,function (err, results, fields) {
        if(err) {
            console.log(err);
            return;
        }

        connection.commit(function (err) {
            if(err) {
                console.log(err);
                return;
            }

            console.log('second query done');
            connection.release();
        })
    });
});

它会导致以下输出

代码语言:javascript
复制
first transaction has started
second transaction has started
second query done
first query done

这意味着第一个连接打开的事务将被忽略,而第二个事务将在此之前完成。但是,当我将连接池用于下面的代码时,

代码语言:javascript
复制
let pool = mysql.createPool({
    connectionLimit:10,
    host: 'localhost',
    user: 'root',
    password: 'thflqkek12!',
    database: 'donationether'
});

pool.getConnection(function (err, connection) {
    connection.beginTransaction(function (err) {
        console.log('first transaction has started');

        if (err) {
            console.log(err);
            return;
        }

        connection.query(`INSERT INTO users VALUES (null, 0, 'username', 'token')`, function (err, results, fields) {
            console.log('first query has started');
            if (err) {
                console.log(err);
                return;
            }

            setTimeout(function () {
                connection.commit(function (err) {
                    if (err) {
                        console.log(err);
                        return;
                    }

                    console.log('first query done');
                    connection.release();
                });
            }, 2000)
        });
    });
});

pool.getConnection(function (err, connection) {
    connection.beginTransaction(function (err) {

        console.log('second transaction has started');

        if(err) {
            console.log(err);
            return;
        }

        connection.query(`UPDATE users SET username = 'c_username' WHERE username = 'username'`,function (err, results, fields) {
            console.log('second query has started');
            if(err) {
                console.log(err);
                return;
            }

            connection.commit(function (err) {
                if(err) {
                    console.log(err);
                    return;
                }

                console.log('second query done');
                connection.release();
            })
        });
    });
});

输出如下

代码语言:javascript
复制
first transaction has started
second transaction has started
first query has started
//2seconds delay
second query has started
first query done
second query done

这意味着第一个事务正在阻止第二个事务的执行。

所以当文件上说

在连接上调用的每个方法都按顺序排队和执行。

这意味着它们是按顺序交付到数据库的,但是即使在事务处理下,它仍然是异步的和并行的。但是,连接池会导致多个连接的实例化,不同池连接中的事务按照每个事务的预期行为。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48969762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档