mysql事务select 只是进行了隔离,保证数据的一致性,并没有加锁,如果要加锁可以用for update。
这句话等于说,我现在开启一个事务,执行select哪怕有上个事务还未结束,也会返回结果
现在库存都是10,并发情况下,都进行了查询库存操作,都返回了10 ,然后每个客户端都进行了10-1操作,所以最终是10单,但是库存只减去了1次
我们如何解决这个问题呢
正常是应该,我开启了事务,如果没有commit或者rollback 的情况下,下一个客户端的select应该是一直等待上一个事务结束,我才能正常select 进行查询,所以这时候,要把select语句锁住,等待上个事务结束,但是这个锁不是真正的锁,只是对开启了事务的数据进行加锁等待
比如现在我要查询全表
select * from table for update
这个时候回立马返回结果,因为并没有开启事务
start transaction
select * from table for update
commit
这时候必须等待 start ... commit 这段代码执行结束后,下个 同样开始事务的 并且进行 select...for update 的才能执行
这时候,同时10个并发,那他们的select ... for update 将都是线性执行的,一个结束才进行下一个操作
而且 for update 是可以针对单个数据的
start transaction
select * from table where id=1 for update
commit
start transaction
select * from table where id=2 for update
commit
这时候哪怕 id=1 还未执行结束,id=2的都会照样执行
但是
start transaction
select * from table where id=1 for update
commit
start transaction
select * from table for update
commit
id=1 是单条数据,指定了索引条件,但是下面这个没有指定,等于是扫码全表,所以,他也会等待id=1结束才执行自己
网友评论