事务是什么
简单的说A表和B表操作属于同一个事务,A表和B表操作需要同时成功同时失败。
Node实现
创建两个表accountA 、accountB
CREATE TABLE IF NOT EXISTS accountB ( id INT NOT NULL AUTO_INCREMENT, amount INT NULL, PRIMARY KEY (id) ); CREATE TABLE IF NOT EXISTS accountA ( id INT NOT NULL AUTO_INCREMENT, amount INT NULL, PRIMARY KEY (id) );
代码实现
我们对两个表都插入一条数据,中间通过执行一个错误的SQL故意制造一个异常。
module.exports = async (pool,isAutoCommit) => { const conn = await pool.getConnection() // 开启事务 isAutoCommit && await conn.beginTransaction() try { // 操作表A let res = await conn.query(` INSERT INTO accountA (amount) VALUES (1) `) // 人为制造异常 res = await conn.query(` KKB `) // 操作表B res = await conn.query(` INSERT INTO accountB (amount) VALUES (1) `) // console.log('INSERT ACCOUNT B ', res) isAutoCommit && await conn.commit() } catch (error) { // console.log('发生error...', error) await conn.rollback() } conn.release() }
测试用例
这里面分成两个用例分别测试有事务和没有事务的情况
- 有事务的时候 出错会回滚 两个表都不会插入数据
- 没有事务的时候 不会回滚 出错前的表插入还将生效
const callback = require('../index') // get the client const mysql = require('mysql2/promise'); // 连接配置 const cfg = { host: "localhost", user: "root", password: "example", // 修改为你的密码 database: "test", // 请确保数据库存在 connectionLimit: 5, // debug:true } test('Test 使用事务', async (done) => { const pool = await mysql.createPool(cfg) // 准备环境 // 所有表数据清空 const conn = await pool.getConnection() // 清理表数据 await conn.query(` TRUNCATE TABLE accountA `) await conn.query(` TRUNCATE TABLE accountB `) await callback(pool, true) // 查询结果 const [countA] = await conn.execute(`SELECT count(*) as count FROM accountA`) const [countB] = await conn.execute(`SELECT count(*) as count FROM accountB`) console.log('AmountA', countA[0].count) console.log('AmountB', countB[0].count) done() // setTimeout(done,4000) }) test('Test 未使用事务', async (done) => { const pool = await mysql.createPool(cfg) // 准备环境 // 所有表数据清空 const conn = await pool.getConnection() // 清理表数据 await conn.query(` TRUNCATE TABLE accountA `) await conn.query(` TRUNCATE TABLE accountB `) await callback(pool, false) // 查询结果 const [countA] = await conn.execute(`SELECT count(*) as count FROM accountA`) const [countB] = await conn.execute(`SELECT count(*) as count FROM accountB`) console.log('AmountA', countA[0].count) console.log('AmountB', countB[0].count) done() // setTimeout(done,4000) })
测试结果
大家可以试试 保持关注 后面我会完善