mysql 锁机制
锁的基本类型
数据库上的操作可以归纳为两种:读和写。
多个事务同时读取一个对象的时候,是不会有冲突的。同时读和写,或者同时写才会产生冲突。因此为了提高数据库的并发性能,通常会定义两种锁:共享锁和排它锁。
使用的是innodb数据库, 两种锁
1.共享锁 (s锁):表示对数据进行读操作。因此多个事务可以同时为一个对象加共享锁。(如果试衣间的门还没被锁上,顾客都能够同时进去参观)
又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
产生共享锁的sql:
begin; sql:select * from ad_plan lock in share mode; commit
sequelize:
try { const transaction = await this.ctx.model.transaction({ autocommit: true, isolationLevel: 'SERIALIZABLE' }); const platformResult = await this.ctx.model.PlatformInfo.findOne( { where: { platform_id, }, transaction, lock: transaction.LOCK.SHARE, } ); await transaction.commit(); } catch(error) { await transaction.rollback(); }
2.排他锁(x锁):读写锁,排他锁表示对数据进行写操作。如果一个事务对对象加了排他锁,其他事务就不能再给它加任何锁了。(某个顾客把试衣间从里面反锁了,其他顾客想要使用这个试衣间,就只有等待锁从里面给打开了)
又称写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。
产生排他锁的sql:
select * from ad_plan for update
sequelize:
try { const transaction = await this.ctx.model.transaction({ autocommit: true, isolationLevel: 'SERIALIZABLE' }); const platformResult = await this.ctx.model.PlatformInfo.findOne( { where: { platform_id, }, transaction, lock: transaction.LOCK.UPDATE, } ); await transaction.commit(); } catch(error) { await transaction.rollback(); }
排他锁使用场景,
平台分数记录在对应的平台数据中,每次平台中的玩家上分下分都会对平台分数进行操作
操作过程:
1.读出平台分数
2.判断平台剩余分数是否可以进行上下分操作
3.增加减少平台分数
该过程中,如果查询出平台分数,还没有进行上下分处理。此时并发又来同样操,则会出现数据错误的并发问题.现再读取平台分数的时候加排他锁,不让其他人进行操作。

浙公网安备 33010602011771号