1
xipushi 2018 年 12 月 17 日 via iPhone 如果程序部署多个,程序锁不搞事的。
一个写库的话,直接 update。update set count=count-1 where count>1,影响行数大于 1,说明成功。 Zookeeper,redis |
3
liunull 2018 年 12 月 17 日 via Android 我们公司是给账户记录加版本号,类似 CAS,冲突就重试,一般单个用户并发修改数据库的概率很小
|
6
Sharuru 2018 年 12 月 17 日 via Android
乐观锁呀,带 version 字段就完事儿了。
|
7
yidinghe 2018 年 12 月 17 日 via Android 假设用户积分为 8,现在要扣掉 5 分,那么 SQL 语句为:
update user set score=score-5 where userid=xxx and score=8 and score>=5 这个语句的作用是在数据库操作层面保证:1、这个扣 5 分的操作只会执行一次; 2、并发的扣分操作只会有一个执行成功; 3、任何成功的扣分操作都不会导致用户积分变成负数。 |
9
lhx2008 OP |
11
xipushi 2018 年 12 月 17 日 @lhx2008 我觉得 score=8 就可以了。
hibernate 的 version 貌似跟 update 语句效果一样,还可以少写几个 SQL。hibernate 默认 session 的生命周期比较反人类。 |
12
xipushi 2018 年 12 月 17 日 纠正上条,是 JPA 的 session.
|
14
lcorange 2018 年 12 月 18 日
MySQL 的 select for update 语法能满足要求么
|
16
sagaxu 2018 年 12 月 18 日 via Android
@lhx2008 只要用 innodb,你直接写 update where version=xxx 一样可能产生行锁,MySQL 会检测死锁。select for update 反而是避免死锁的办法。
To avoid deadlocks when performing multiple concurrent write operations on a single InnoDB table, acquire necessary locks at the start of the transaction by issuing a SELECT ... FOR UPDATE statement for each group of rows expected to be modified, even if the data change statements come later in the transaction. https://dev.mysql.com/doc/refman/8.0/en/internal-locking.html |