mysql中的锁分为两类:悲观锁和乐观锁
悲观锁:悲观锁的特点是先拿到所在进行业务操作,即“悲观”的认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作。通常所说的“一锁二查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。
注意:不同的数据库对select for update的支持是不一样的。Oracle数据库中select for update no wait表示拿不到锁就会报错而不是等待,mysql数据库则没有no wait但是mysql数据库如果长时间拿不到锁也会报错。
mysql数据库使用select for update的时候如果不指定索引,则会对整个表进行锁定,指定就是对本行数据进行锁定。
乐观锁:乐观锁的特点先进行业务操作,不到万不得已不去拿锁。即“乐观”的认为拿锁多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步再去拿一下锁就好。
乐观锁的实现基本不需要数据库的支持,再表加一个字段表示当前版本号,在每次跟新的时候版本号+1,判断当前数据库版本是否是之前所读取的版本。
id | name | version |
1 | 张三 | 1 |