方案2 在数据库层串行化, 使用SELECT .... FOR UPDATE实现,(前提MYSQL是InnoDB引擎, 并且每个请求都在一个独立的事务中) 原理是 A请求过来查询库存 SELECT * FROM goods WHERE id = 1 FOR UPDATE; 此时ID = 1的数据行已经加了共享锁, 此所不阻塞普通的SELECT, 另外B请求过来 同样执行了SELECT * FROM goods WHERE id = 1 FOR UPDATE; 此时, B请求会被阻塞, 知道A请求操作完成, 事务提交后, 才能拿到锁, 执行下面的操作. 举个🌰
mysql>select*from tx_test where a =4forupdate; mysql>select*from tx_test where a =4forupdate; +---+------+ | a | b | +---+------+ |4|1000| +---+------+ 1rowinset (0.00 sec)
mysql>update tx_test set b =1where a =4; Query OK, 1row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>commit; +---+------+ Query OK, 0rows affected (0.09 sec) | a | b | +---+------+ |4|1| +---+------+ 1rowinset (24.81 sec)