在MySQL中,假设有一种账户表,有一个账户金额字段,每当有响应操作时需要更新账户金额,那么这个时候就需要考虑并发问题,比如账户原有金额100元,现在有100个人同时给这个账户转账,此时数据库就会有多个线程来操作账户金额字段,我们能不能直接利用MySQL的能力完成并发操作?
答案是肯定的,解决的SQL就是:
update user_account set amount = amount + x where user_id = 1;
这句SQL就能保证并发,这是数据库系统必须要解决的问题。在对数据进行写操作时,需要对相应数据加上排他锁,即时使用了MVCC,也只能让读写并发,写和写之间一定是会串行的,这是数据库保证的。所以上面的SQL是可以放心的在并发环境下执行并能够得出正确结果。
第二种情况
但是这种情况仅仅适用于修改字段目标值比较简单的情况,可以在SQL中完成运算,如果有场景是必须先查出来目标值,然后经过复杂计算(比如调用其他服务计算),最后写入,这种情况就无法直接通过一条SQL解决。
通常这种情况,如果想使用乐观锁的思想,需要在表里面新增一个整型的version字段,修改前查出目标值和version=v1,然后经过计算,写入时
update user_account set amount=x,version=version+1 where version=v1 and user_id=u
这样就可以利用乐观锁的思想了。
这里还有一个不成熟的思想,就是目标值本身来作为version。