oracle数据库分行级锁和表级锁。用select * from table-name for update完成行级锁。用delete或update完成表级锁。你锁定的资源 别人会等待你的提交语句或回退语句完成以后再继续进行。
创新互联是一家专业提供永新企业网站建设,专注与成都网站设计、做网站、H5技术、小程序制作等业务。10年已为永新众多企业、政府机构等服务。创新互联专业网站制作公司优惠进行中。
如果当前有用户在对某行数据进行修改登操作,oracle会在这行数据上添加行级锁,期间,所有用户对该行数据只能查询,不可修改,如果比如说执行update操作,需等待该修改操作事务提交或者回滚之后,才行。
乐观锁一开始也说了,就是一开始假设不会造成数据冲突,在最后提交的时候再进行数据冲突检测。在乐观锁中,我们有3种
常用的做法来实现。
[1]第一种就是在数据取得的时候把整个数据都copy到应用中,在进行提交的时候比对当前数据库中的数据和开始的时候更新前取得的数据。当发现两个数据一模一样以后,就表示没有冲突可以提交,否则则是并发冲突,需要去用业务逻辑进行解决。
[2]第二种乐观锁的做法就是采用版本戳,这个在Hibernate中得到了使用。采用版本戳的话,首先需要在你有乐观锁的数据库table上建立一个新的column,比如为number型,当你数据每更新一次的时候,版本数就会往上增加1。比如同样有2个session同样对某条数据进行操作。两者都取到当前的数据的版本号为1,当第一个session进行数据更新后,在提交的时候查看到当前数据的版本还为1,和自己一开始取到的版本相同。就正式提交,然后把版本号增加1,这个时候当前数据的版本为2。当第二个session也更新了数据提交的时候,发现数据库中版本为2,和一开始这个session取到的版本号不一致,就知道别人更新过此条数据,这个
时候再进行业务处理,比如整个Transaction都Rollback等等操作。在用版本戳的时候,可以在应用程序侧使用版本戳的验证,也可以在数据库侧采用Trigger(触发器)来进行验证。不过数据库的Trigger的性能开销还是比较的大,所以能在应用侧进行验证的话还是推荐不用Trigger。
[3]第三种做法和第二种做法有点类似,就是也新增一个Table的Column,不过这次这个column是采用timestamp型,存储数据最后更新的时间。在Oracle9i以后可以采用新的数据类型,也就是timestamp with time zone类型来做时间戳。这种Timestamp的数据精度在Oracle的时间类型中是最高的,精确到微秒(还没与到纳秒的级别),一般来说,加上数据库处理时间和人的思考动作时间,微秒级别是非常非常够了,其实只要精确到毫秒甚至秒都应该没有什么问题。和刚才的版本戳类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。如果不想把代码写在程序中或者由于别的原因无法把代码写在现有的程序中,也可以把这个时间戳乐观锁逻辑写在Trigger或者存储过程中。
在对指定表做append操作,其他再做truncate时候,会产生锁表,如下验证步骤,
1、创建测试表,
create table test_lock(id number, value varchar2(200));
2、执行append语句;并且不做提交,insert /*+append*/ into test_lock values(1,1);
3、再次执行清表语句,truncate table test_lock;报锁表错误,
4、查看锁表语句,发现被锁表,
select b.object_name, t.*
from v$locked_object t, user_objects b
where t.object_id = b.object_id