锁的由来
- 开发多用户、数据库驱动时,一个比较大的难点是:一方面要最大程度的利用数据库的并发访问,另外一方面还要确保每一个用户能以一致的方式读取和修改数据。
- 锁机制主要是管理对于共享资源的并发访问。
锁存在的问题
通过锁定机制可以实现事物的隔离性,使事物可以并发的工作。锁提高了并发,但是带来了三种问题:
脏读
脏数据是事务对缓冲池中行记录的修改,而且没有被提交。一个事务读取到另外一个事务中未提交的数据,违反了数据库的隔离性。
脏读发生的前提是数据库事务的隔离级别为read uncommit.不可重复读
一个事务多次读取同一数据集合,在这个事务没有结束时,另外一个事务也访问该数据集合, 并做了一下dml操作,因此第一个事务中的两次读数据之间,由于第二个事务的修改,第一个事务两次读取到的数据是不一样的。丢失更新
丢失更新是另外一个锁导致的问题,是一个事务的更新操作会被另外一个事务的更新操作覆盖,从而导致数据不一致。要避免丢失更新的发生,事务在这种情况下的操作编程串行化,而不是并行操作。
并发控制
悲观锁
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作悲观锁假定其他用户企图访问或者改变你正在访问、更改的对象的概率是很高的,因此在悲观锁的环境中,在你开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁。悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。乐观锁
假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 乐观锁不能解决脏读的问题。 乐观锁则认为其他用户企图改变你正在更改的对象的概率是很小的,因此乐观锁直到你准备提交所作的更改时才将对象锁住,当你读取以及改变该对象时并不加锁。可见乐观锁加锁的时间要比悲观锁短,乐观锁可以用较大的锁粒度获得较好的并发访问性能。但是如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时,数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。这说明在乐观锁环境中,会增加并发用户读取对象的次数。
参考文档
- 乐观锁与悲观锁的区别 http://www.cnblogs.com/Bob-FD/p/3352216.html