select .......for update
除了有查询的作用外,还会加锁,那么select......for update会锁表还是锁行?
验证:
CREATE TABLE `student` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`age` int NOT NULL,
`phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `index_phone` (`phone`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
插入模拟数据:
INSERT INTO `student` (`id`, `name`, `age`, `phone`)
VALUES
(1, '22222', 1, '111'),
(2, '英语', 2, '1212'),
(3, '22222', 3, '2121'),
(4, '22222', 4, '21212'),
(5, '1111111', 5, '4444');
用到的索引相关命令
#查询表student的所有索引
show index from student
#id是自增主键
#age 创建普通索引
CREATE INDEX idx_age ON student (`age`);
#phone创建唯一索引
CREATE UNIQUE INDEX index_phone ON student(phone);
#name是普通字段
#age 创建普通索引,
#phone创建唯一索引

需要关闭自动提交,通过set @@autocommit=0; 设置为手动提交。0代表手动提交,1代表自动提交。
实例1(主键):
会话1查询id=1的数据加了for update悲观锁,开启事务,并且没有提交。

会话2去更新id为1的数据,被阻塞了








@Select("select * from tb_goods where goods_id = #{goodsId} for update")
public TbGoods lock(String goodsId);
@Service
public class OrderService {
@Autowired
private TbGoodsMapper goodsMapper;
@Autowired
private TbOrderMapper orderMapper;
@Transactional
public void buy(String goodsId){
//获取数据库悲观锁(行锁)
goodsMapper.lock(goodsId);
//1:查询商品信息
TbGoods tbGoods = goodsMapper.selectById(goodsId);
if (tbGoods == null) {
return;
}
//2:判断库存
if(tbGoods.getGoodsStock1() <= 1){
return;
}
//3:下单
TbOrder tbOrder = new TbOrder();
tbOrder.setOrderId(UUID.randomUUID().toString());
tbOrder.setGoodsId(Integer.parseInt(goodsId));
tbOrder.setOrderAmount(tbGoods.getGoodsPrice());
orderMapper.insert(tbOrder);
//4:修改库存
tbGoods.setGoodsStock1(tbGoods.getGoodsStock1() - 1);
goodsMapper.updateById(tbGoods);
}
}

文章转载自程序员恰恰,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。