数据库锁机制
2015-09-03 16:57
309 查看
数据库就是通过锁机制来解决并发问题的。
主要就是两种锁,共享锁和排他锁(也叫独占锁)。在执行select语句的时候需要给操作对象(表或者一些记录)加上共享锁,但加锁之前需要检查是否有排他锁,如果没有,则可以加共享锁(一个对象上可以加n个共享锁),否则不行。共享锁通常在执行完select语句之后被释放,当然也有可能是在事务结束(包括正常结束和异常结束)的时候被释放,主要取决与数据库所设置的事务隔离级别。执行insert、update、delete语句的时候需要给操作的对象加排他锁,在加排他锁之前必须确认该对象上没有其他任何锁,一旦加上排他锁之后,就不能再给这个对象加其他任何锁。排他锁的释放通常是在事务结束的时候(当然也有例外,就是在数据库事务隔离级别被设置成Read Uncommitted(读未提交数据)的时候,这种情况下排他锁会在执行完更新操作之后就释放,而不是在事务结束的时候)。
数据库是支持在一个事务中进行自动锁升级的,例如,在某个事务中先执行select语句,后执行update语句,这两条语句操作了同一个对象,并且假定共享锁是在事务结束的时候被释放的。如果数据库不支持自动锁升级,那么当update语句请求排他锁的时候将不能成功。因为之前select语句的共享锁没有被释放,那么事务就进入了无限等待,即死锁。有了自动锁升级,在执行update语句的时候就可以将之前加的共享锁升级为排他锁,但有个前提,就是这个共享锁必须是本事务自己加的,而且在操作对象上没有在加其他任何锁,否则共享锁是不能被升级为排他锁的,必须等待其他锁的释放。
在看《精通Hibernate》的时候,里面还提到了更新锁。因为通常在执行更新操作的时候要先查询,也就是我们通常会在update语句和delete语句中加where子句。那么,有的数据库系统可能会在执行查询的时候先给操作对象加共享锁,然后在更新的时候加排他锁,但这么做会有问题,也就是如果两个事务同时要更新一个对象,都先给这个对象加了共享锁,当要更新的时候,都请求升级锁,但由于这个对象上存在对方事务加的共享锁。。所以无法升级。这样两个事务就在等待对方释放共享锁,进入死锁状态。更新锁就是为了解决这个问题,即在执行查询操作的时候加的不是共享锁而是更新锁(一个对象上只能有一个更新锁和n个共享锁),当要更新的时候,再将更新锁升级为排他锁,升级前提是这个对象上只有本事务加的更新锁,没有其他任何锁了。其实,我想,如果在执行查询的时候就给事务加排他锁不也能解决死锁问题吗,但这样似乎会减弱系统的并发性能。
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- 数据库链接字符串查询网站
- DB2实例管理
- DB2实例管理
- 保障MySQL数据安全的14个最佳方法
- mysql问答汇集
- 创建一个空的IBM DB2 ECO数据库的方法
- Access 2000 数据库 80 万记录通用快速分页类
- 开通一个数据库失败的原因的和解决办法
- 一个简单的asp数据库操作类
- CentOS下DB2数据库安装过程详解
- EasyASP v1.5发布(包含数据库操作类,原clsDbCtrl.asp)第1/2页
- sql2008 还原数据库解决方案
- Oracle 数据库自动存储管理-安装配置
- 基于oracle中锁的深入理解
- Oracle 数据库 临时数据的处理方法
- 数据库分页查询语句数据库查询
- 最近比较流行的数据库挂马
- 分割超大Redis数据库例子