乐趣区

关于node.js:Nodejs-mysql-事务和锁的写法

一、装置相干包

npm install access-db
npm install dotenv

而后在我的项目入口文件 (如 app.js) 的最后面引入 require('dotenv').config()
新建 .env 文件,并增加 mysql 配置。

  MYSQL_HOST=localhost   // 必填
  MYSQL_USER=root
  MYSQL_PASSWORD=123456
  MYSQL_PORT=3306
  MYSQL_DATABASE=    // 必填  数据库名

二、事务和锁 transaction()

事务处理的异步函数

let {run, begin, rollback, commit, locks} = await mysql.transaction()

参数 类型 必填 阐明
begin Function 事务开始函数
commit Function 事务提交函数
rollback Function 回滚事务函数
run Function 执行 sql 语句函数
locks Object 上锁类型

locks 详情

field value 阐明
shared_locks ‘ lock in share mode’ 共享锁 Shared Locks(简称 S 锁,属于行锁)
exclusive_locks ‘ for update’ 排他锁 Exclusive Locks(简称 X 锁,属于行锁)

begin()为事务开启函数,在 begin() 函数外面执行数据库操作,通过 run() 来执行各个 sql 语句,并返回后果。当执行报错,或执行的 sql 后果不满足条件时,能够用 rollback() 函数进行回滚操作。当执行没问题时,记得提交事务,即执行 commit() 函数。

如果须要相似秒杀流动那种业务。那么,还须要对数据进行加锁,间接在返回 sql 语句 前面,加上 locks 对应的类型即可。

示例代码:

import {mysql} from 'access-db'

/** mysql 的事务 和 锁 */
let {run, begin, rollback, commit, locks} = await mysql.transaction()

await begin(async () => {
  try{
    // 须要加锁的时候,就间接在返回的 sql 语句前面加上相应的锁,留神要将 await 括起来
    let sql1 = (await mysql.get('user', 10, 'sentence')) + locks.exclusive_locks
    let sql2 = await mysql.update('user', 10, {money: ['incr', -3]}, 'sentence')
    let sql3 = await mysql.update('user', 12, {money: ['incr', 3]}, 'sentence')

    let res1 = await run(sql1)
    if(res1.data.money < 3){return await rollback()  // 回滚事务
    }
    await run(sql2)
    await run(sql3)
    await commit()  // 提交事务}catch(err){await rollback()  // 回滚事务
    throw new Error(err)
  }
})
退出移动版