记 mysql 并发更新时的表锁问题
最近在做一个 nodejs 项目时遇到的一个基础的 mysql 问题,下面记录一下。
问题
当对数据表中的数据做更新操作时,如果并发的对同一条数据进行更新,那么后面触发的会有一定概率更新失败。
原因
mysql innodb 的行锁基于索引的,当我们执行下面这条更新语句时,会触发 mysql 的排它锁,如果更新还没完成,其他对于 id=1 的更新操作会执行失败
update tableName set field = newField where id=1
解决
通过用事务的方式来执行这种高并发的语句,可以解决这个问题。
数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行。
当前一个事务没有执行完成时,下面的只能等待当前事务完成,才会执行。
sequelize 代码
await sequelize.transaction({}, async (transaction) => {
const instance = await model.findOne({
where: {
id: 1,
},
transaction,
})
await instance.update({
field: newField,
}, {
transaction,
})
})
记 mysql 并发更新时的表锁问题
最近在做一个 nodejs 项目时遇到的一个基础的 mysql 问题,下面记录一下。
问题
当对数据表中的数据做更新操作时,如果并发的对同一条数据进行更新,那么后面触发的会有一定概率更新失败。
原因
mysql innodb 的行锁基于索引的,当我们执行下面这条更新语句时,会触发 mysql 的排它锁,如果更新还没完成,其他对于 id=1 的更新操作会执行失败
解决
通过用事务的方式来执行这种高并发的语句,可以解决这个问题。
数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行。
当前一个事务没有执行完成时,下面的只能等待当前事务完成,才会执行。
sequelize 代码