锁的基本类型
数据库上的操作可以归纳为两种:读和写。
多个事务同时读取一个对象的时候,是不会有冲突的。同时读和写,或者同时写才会产生冲突。因此为了提高数据库的并发性能,通常会定义两种锁:共享锁和排它锁。
使用的是innodb数据库, 两种锁
1.共享锁 (s锁):表示对数据进行读操作。因此多个事务可以同时为一个对象加共享锁。(如果试衣间的门还没被锁上,顾客都能够同时进去参观)
产生共享锁的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锁):读写锁,排他锁表示对数据进行写操作。如果一个事务对对象加了排他锁,其他事务就不能再给它加任何锁了。(某个顾客把试衣间从里面反锁了,其他顾客想要使用这个试衣间,就只有等待锁从里面给打开了)
产生排他锁的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.增加减少平台分数
该过程中,如果查询出平台分数,还没有进行上下分处理。此时并发又来同样操,则会出现数据错误的并发问题.现再读取平台分数的时候加排他锁,不让其他人进行操作。