乐观锁和悲观锁
但是事情是可能有多个用户同时操作了一个数据字段,并且要对数据库提交了修改,此时为了保护数据的正确性,所以人们想出了一个办法来解决这种情况:使用版本控制或者时间戳。
简单介绍一下版本控制和时间戳,他们的功能是为了保证一个操作从读取数据到更改数据提交的这段过程中,没有其他的操作修改过这个数据字段。
实现起来也比较简单,为每个字段创建一个版本号,version,每次需要读取这个字段时将版本号也读取出来,然后提交修改的时候带上读取的版本号,将事先读取的版本号和现在数据库对应字段的版本号进行比较,如果据库里的版本号等于事先读取的版本号,说明这段时间没有其他操作修改过这个字段,然后将本次修改提交,并将版本号version+1。
如果数据库里的版本号比事先读取的版本号大,说明在这次操作时间内已经有其他操作修改的这个字段,因此这次提交是无效的,不能完成提交。
时间戳的方法类似,不过将判断的方式改成了提交时间的变化。
悲观锁:Pessimistic Concurrency Control,缩写“PCC”,是一种并发控制的方法。
悲观锁和乐观锁的观点相反,他认为为了自己的操作会被别的操作所影响,所以在自己操作数据库某个字段时,别的操作都不能进行。
悲观锁操作数据库时,会事先尝试在该字段加排它锁(加锁之后其他操作均不可进行),如果加锁失败则表明有其他的操作在使用这个字段,这样就需要等待知道其他操作完成释放锁,当获得锁并完成操作之后再将锁释放供其他操作使用。
数据库实现悲观锁有两种类型,行锁和表锁。InnoDB使用行锁,MyISAM只能使用表锁。
顾名思义表锁是将整张表锁住,消耗资源更大,并发能力弱,行锁则只锁住需要操作的那一行数据,并发能力强一些。
行锁的使用必须保证索引能够使用,换句话说如果在一次操作中没有使用索引,则不会使用行锁而是表锁。
总结:
悲观锁的并发能力比乐观锁弱。
乐观锁可能会出现冲突,悲观锁不会出现冲突。
在读多写少的场合,乐观锁的使用效果比悲观锁好些。
在不允许脏读,对数据库的安全要求较高的场合,还是使用悲观锁好。