悲观锁,悲观锁和乐观锁的用处和区别?

维修要闻     2020-12-24    浏览:20

悲观锁和乐观锁的用处和区别?

用处:保证数据安全,处理多用户并发访问。

区别:

悲观锁,从数据开始更改时就将数据锁住,知道更改完成才释放。
乐观锁,直到修改完成准备提交所做的的修改到数据库的时候才会将数据锁住。完成更改后释放。

悲观锁会造成访问数据库时间较长,并发性不好,特别是长事务。乐观锁在现实中使用得较多,厂商较多采用。



请问一个悲观锁的问题,就是在程序中实现该如何做啊,谢谢

假如要按照你这种 悲观锁 的处理机制的话, 那么
Connection conn 要定义在外面, 也就是类这个级别。

例如
public class Test {
Connection conn;

public Product get(id) {
conn = getConn();
conn.startTraction();
...............select * from product where id = 10 for update;
}


public void update(long id) {
// 这个时候, 用类一个级别的 Conn , 不用新建
update product set name = "xxx" where id = :id;
// 更新完毕后
Commit 事务。
关闭 Conn.
}
}

上面的只是 原理的 例子, 实际情况下,不推荐这么写
因为 如果有人 只 Product get(id) 不 update(long id) 的话, 事情就麻烦了。
悲观锁和乐观锁,什么情况

  锁。我们知道,最常用的处理多用户并发访问的方法是加锁。当一个用户锁住数据库中的某个对象时,其他用户就不能再访问该对象。加锁对并发访问的影响体现在锁的粒度上。比如,放在一个表上的锁限制对整个表的并发访问;放在数据页上的锁限制了对整个数据页的访问;放在行上的锁只限制对该行的并发访问。可见行锁粒度最小,并发访问最好,页锁粒度最大,表锁介于2者之间。锁有两种:悲观锁和乐观锁。悲观锁假定其他用户企图访问或者改变你正在访问、更改的对象的概率是很高的,因此在悲观锁的环境中,在你开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁。悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。与悲观锁相反,乐观锁则认为其他用户企图改变你正在更改的对象的概率是很小的,因此乐观锁直到你准备提交所作的更改时才将对象锁住,当你读取以及改变该对象时并不加锁。可见乐观锁加锁的时间要比悲观锁短,乐观锁可以用较大的锁粒度获得较好的并发访问性能。但是如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时,数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。这说明在乐观锁环境中,会增加并发用户读取对象的次数。

  从数据库厂商的角度看,使用乐观的页锁是比较好的,尤其在影响很多行的批量操作中可以放比较少的锁,从而降低对资源的需求提高数据库的性能。再考虑聚集索引。在数据库中记录是按照聚集索引的物理顺序存放的。如果使用页锁,当两个用户同时访问更改位于同一数据页上的相邻两行时,其中一个用户必须等待另一个用户释放锁,这会明显地降低系统的性能。interbase和大多数关系数据库一样,采用的是乐观锁,而且读锁是共享的,写锁是排他的。可以在一个读锁上再放置读锁,但不能再放置写锁;你不能在写锁上再放置任何锁。锁是目前解决多用户并发访问的有效手段。
java中悲观锁和乐观锁的区别

悲观锁机制:
String hqlStr = " from TUser as user where user.name=’Erica’ " ;
2 Query query = session.createQuery(hqlStr);
3 query.setLockMode( " user " ,LockMode.UPGRADE); // 加锁
4 List userList = query.list(); // 执行查询,
乐观锁机制:
< hibernate - mapping >
< class
name = " org.hibernate.sample.TUser "
table = " t_user "
dynamic - update = " true "
dynamic - insert = " true "
optimistic - lock = " version "
>
……
</ class >
</ hibernate - mapping >

仅供参考

相关搜索

相似文章