2022年3月13日
悲观锁
JavaWeb 并发:FOR UPDATE 实战,监测并解决。 – 程序员泥瓦匠 – 博客园 (cnblogs.com)
以上文章是一个具体的例子
假设有个表table,f1,f2,f3三个字段,我们要做的事
1.select * from a where id = x;
2.update a set f1=f1+10, f2=f2-20, f3=f3+30 where id = xx;
3.提高并发数量
以上处理,在并发大的时候,可以报数据库的连接错误,也可能出现数据f1,f2,f3不符合我们预想的情况
可以使用for update来处理,使用悲观锁之后,在解锁之前,其他事务不能修改锁住的数据。
https://zhuanlan.zhihu.com/p/74875550 for update 的作用和目的: select for update 是为了在查询时,对这条数据进行加锁,避免其他用户以该表进行插入,修改或删除等操作,造成表的不一致性. 几个类似的场景: select * from t for update 会等待行锁释放之后,返回查询结果。 select * from t for update nowait 不等待行锁释放,提示锁冲突,不返回结果 select * from t for update wait 5 等待5秒,若行锁仍未释放,则提示锁冲突,不返回结果 select * from t for update skip locked 查询返回查询结果,但忽略有行锁的记录 SELECT...FOR UPDATE 语句的语法如下: SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED]; 其中: OF 子句用于指定即将更新的列,即锁定行上的特定列。 WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。 “使用FOR UPDATE WAIT”子句的优点如下: 1防止无限期地等待被锁定的行; 2允许应用程序中对锁的等待时间进行更多的控制。 3对于交互式应用程序非常有用,因为这些用户不能等待不确定 4 若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告
当然,很多时候我们数据是多读少写的,如svn、git等模式,直接使用乐观锁,既增加版本或者比较当前值等方式来更新数据。