我现在有一张类似于下面这样的数据库表:
id | name | is_used |
---|---|---|
1 | name1 | 1 |
2 | name2 | 0 |
is_used
字段用来标记该条数据是否已经被使用过了。
客户端会向服务器请求可用数据,服务端返回一条可用的数据,即is_used
字段为 false。同时设置该条数据为已使用状态,即设置is_used
字段为 true。
在这个过程中,如何确保两个客户端不会获取到同一条数据呢?会不会出现前一个请求的数据库操作中还未完成设置该条数据is_used
字段为 true的操作,而这是后一个请求到达,导致返回了同一条数据的情况?如果会的话,有没有什么好的办法解决呢?
我现在考虑的是,通过同步 http 请求或者是将数据预先放在一个缓存队列中,然后从队列中同步的读取数据。不知道大家有没有好的方案?多谢指教。
环境:Express、PostgreSQL, orm 使用 Sequelize。
以前用mongo的时候遇到过这种问题,只要保证操作的原子性就可以解决了
用本身的原子操作啊,像findOneAndUpdate
刚刚又去了解一下事务相关的内容,确实因为原子性和隔离性可以保证不会读到已经使用的数据,受教了。
我以前是做 PHP 的,一个解决方案就是乐观锁,配合事务处理,为每一个客户端使用独立的数据库连接来保证独立性。在数据表中存储一个保存状态的字段,在更新数据前先获取数据,然后再保存数据时同时提交状态字段在 where 条件中,如果保存成功则提交事务,如果失败,即状态被改变,则回滚。
补充一句,这个状态字段一般保存布尔值,而是保存数值,例如商品的个数。