mysql锁的使用总结

来总结一下mysql数据库锁的使用.
目前,我所知道的数据库锁就是悲观锁和乐观锁.一般用到数据库锁的场景都是对数据的准确性比较高的,比如钱等.由于水平有限,这里不研究原理,只看看怎样去使用数据库锁.
首先,对于悲观锁,也就是我们默认每次的更新都是非常不安全的操作,我们得给她加锁.相当于java里面的synchronized.在mysql里面这样使用:

select xxx for update

也就是假如我们要对id=1的用户更新money,那么我们就需要在spring事务方法里面这样写:

@Transaction
public void updateMoney() {
    User user = userDao.findById(1);
    user.setMoney(100.00);
    userDao.update(user);
}

在这个事务结束之前,这条记录都无法被别的事务更新.
悲观锁通过锁定一行记录来进行更新,但是这样锁住其实也就一定程度上造成了效率的下降.因此,有时候我们也使用乐观锁来代替悲观锁.
乐观锁,意思就是我们认为每次更新都是不会出错的.相当于java里面的compareAndSet.我们不需要对行记录加锁,我们通过判断行的版本变化来决定我们的更新动作.通常做法是新加一个version字段.利用cas思想:

 update user set money = 100.00 where id=1 and version=1
  1. 我们取出一行数据,假设version=1
  2. 更新的时候,我们期望数据库的version也应该是1,如果不是,那么说明别的事务对这行记录进行了更新.
  3. 我们重复上面的俩步操作.
    这种思想和cas是一样的,我们不停的判断更新,可以预料最终肯定会成功的.那么,这里会一直重复进行判断.首先,我们要有一个循环的限制,不能一直循环吧,那多少合适就需要考虑好.而且,我们这里能看到每次都是有一个查询然后再更新的操作,如果有大量的并发请求,那么对数据库的压力也很大.因此,虽然乐观锁看起来降低了锁操作,但是有些情况看起来并不是那么美好.
    上面俩种就是常用的数据库锁机制,接下来说一下另一种更新的操作.
update user set money = money+100.00 where id = 1;

我们不需要先取出行记录,也不需要加锁,直接传一个我们需要更新的值就可以了.首先我们知道一个单纯的update操作,mysql是默认加锁的,也就是不可能存在同时修改同一行的情况,那么就不会出现并发数算错的情况了.我试了下,并发情况下也是正确的.但是好像我并没有看到别人用这种写法.并不是很明白,难道不应该在mysql里面加减,她算不准确?效率不高?可能我水平有限,还没法理解mysql太底层的东西,至少目前来说我觉得这种写法是没有啥问题的.
好了,mysql锁在使用的时候还是非常方便的.至于选取哪种方式去更新,就要自己根据当前的业务场景进行判断了.另外死锁的话,我觉得更多的需要的是在代码层面考虑,mysql死锁也是会强制重启事务,就算不重启,事务也会在一定时间失效的.还有平常我觉得数据并发不大,对数据不是要求很精确的话都不需要考虑锁的,比如点赞,产生数据丢失我觉得都无所谓.一个人可能会关心一篇文章是一个赞还是两个赞,但谁会去关心一篇文章是12001的赞还是12002个赞呢,是吧.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值