本人前端,最近在写一个后台管理系统,没有后端经验特来请教一下,场景是这样的: 两个人同时进页面获取了某条记录的详情,此时是一样的,然后一个人修改了这条数据,如订单状态,然后不希望第二个人再次更改了。代码需要怎么写? 是每次update之前先select出来判断订单状态么,还是要表加锁之类的?
如果是后台管理系统,并发度特别低,并且是单条SQL就可以完成。你完全可以不用考虑。
但当你涉及操作的表特别多,此时你可以放在一个事务里面处理,这样不需要给表加锁。毕竟给表加锁的性能比较低
如果你的数据库支持行锁,假设你使用的MySQL5.5+
你可以使用SELECT … FOR UPDATE
或SELECT ... LOCK IN SHARE MODE
这两者有一定区别。
前者是排他锁。加锁之后其他人不能读取,当需要读取时遇到加锁了必须等待。吞吐量低,查询受影响
后者是共享锁,锁了之后其他人可以读取,但是不能修改和删除。写吞吐量低,查询不受影响
这两者都是悲观锁,还有一种是乐观锁。在db 表里面加一个版本号或者是时间戳,写之前先查。最后以版本号或者是时间戳作为条件来更新。版本号就是update ...,set version+1 where version=xxx
.时间戳就是update ... set time=now() where time=xxxx
可以在update语句中增加条件,只对状态为某种情况的数据进行修改. 然后根据返回的effect rows 来判断是否更新成功.
本来如果是普通java应用,根据主键加锁阻塞线程反而是最简单的,不过估计你是node.js,只能考虑分布式锁和数据库锁了.
可以在update语句中增加条件,只对状态为某种情况的数据进行修改. 然后根据返回的effect rows 来判断是否更新成功.
本来如果是普通java应用,根据主键加锁阻塞线程反而是最简单的,不过估计你是node.js,只能考虑分布式锁和数据库锁了.
加个字段,控制权限不就好了? 例如,加个字段updatedBy, 非这个字段的用户 或 超级管理员什么的,不可对这条数据修改,删除
lz 先了解下 事物隔离 以及相关的锁。
需要了解的有单个事务,并发事务,事务隔离级别,排他锁(x锁),共享锁(s锁),不同的数据库管理系统,不同的存储引擎有所差别,比如postgresql和mysql是不一样的,mysql的不同存储引擎也是不一样的,比如支持的锁的粒度等。锁的粒度会影响到数据库处理并发事务的能力,TPS(每秒处理的事务数量)。