Oracle创建悲观锁和乐观锁为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突 。为了解决这个问题,大多数数据库用的方法就是数据的锁定 。
数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁 。什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住 。而乐观锁就是认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测 , 如果发现冲突了 , 则让用户返回错误的信息,让用户决定如何去做 。
先从悲观锁开始说 。在SqlServer等其余很多数据库中,数据的锁定通常采用页级锁的方式,也就是说对一张表内的数据是一种串行化的更新插入机制 , 在任何时间同一张表只会插1条数据,别的想插入的数据要等到这一条数据插完以后才能依次插入 。带来的后果就是性能的降低,在多用户并发访问的时候,当对一张表进行频繁操作时,会发现响应效率很低,数据库经常处于一种假死状态 。而Oracle用的是行级锁,只是对想锁定的数据才进行锁定,其余的数据不相干,所以在对Oracle表中并发插数据的时候,基本上不会有任何影响 。
注:对于悲观锁是针对并发的可能性比较大 , 而一般在我们的应用中用乐观锁足以 。
Oracle的悲观锁需要利用一条现有的连接,分成两种方式,从SQL语句的区别来看,就是一种是for update,一种是for update nowait的形式 。比如我们看一个例子 。首先建立测试用的数据库表 。
CREATE TABLE TEST(ID,NAME,LOCATION,VALUE,CONSTRAINT test_pk PRIMARY KEY(ID))AS SELECT deptno, dname, loc, 1 FROM scott.dept
这里我们利用了Oracle的Sample的scott用户的表,把数据copy到我们的test表中 。首先我们看一下for update锁定方式 。首先我们执行如下的select for update语句 。
select * from test where id = 10 for update
通过这条检索语句锁定以后,再开另外一个sql*plus窗口进行操作 , 再把上面这条sql语句执行一便,你会发现sqlplus好像死在那里了,好像检索不到数据的样子,但是也不返回任何结果,就属于卡在那里的感觉 。这个时候是什么原因呢,就是一开始的第一个Session中的select for update语句把数据锁定住了 。由于这里锁定的机制是wait的状态(只要不表示nowait那就是wait) , 所以第二个Session(也就是卡住的那个sql*plus)中当前这个检索就处于等待状态 。当第一个session最后commit或者rollback之后,第二个session中的检索结果就是自动跳出来,并且也把数据锁定住 。不过如果你第二个session中你的检索语句如下所示 。
select * from test where id = 10
也就是没有for update这种锁定数据的语句的话,就不会造成阻塞了 。另外一种情况,就是当数据库数据被锁定的时候,也就是执行刚才for update那条sql以后,我们在另外一个session中执行for update nowait后又是什么样呢 。比如如下的sql语句 。由于这条语句中是制定采用nowait方式来进行检索 , 所以当发现数据被别的session锁定中的时候,就会迅速返回ORA-00054错误,内容是资源正忙, 但指定以 NOWAIT 方式获取资源 。所以在程序中我们可以采用nowait方式迅速判断当前数据是否被锁定中 , 如果锁定中的话,就要采取相应的业务措施进行处理 。
select * from test where id = 10 for update nowait
那这里另外一个问题,就是当我们锁定住数据的时候 , 我们对数据进行更新和删除的话会是什么样呢 。比如同样,我们让第一个Session锁定住id=10的那条数据 , 我们在第二个session中执行如下语句 。
update test set value=https://www.04ip.com/post/2 where id = 10
这个时候我们发现update语句就好像select for update语句一样也停住卡在这里,当你第一个session放开锁定以后update才能正常运行 。当你update运行后,数据又被你update语句锁定住了 , 这个时候只要你update后还没有commit,别的session照样不能对数据进行锁定更新等等 。
总之,Oracle中的悲观锁就是利用Oracle的Connection对数据进行锁定 。在Oracle中,用这种行级锁带来的性能损失是很小的,只是要注意程序逻辑 , 不要给你一不小心搞成死锁了就好 。而且由于数据的及时锁定,在数据提交时候就不呼出现冲突,可以省去很多恼人的数据冲突处理 。缺点就是你必须要始终有一条数据库连接,就是说在整个锁定到最后放开锁的过程中,你的数据库联接要始终保持住 。与悲观锁相对的,我们有了乐观锁 。乐观锁一开始也说了,就是一开始假设不会造成数据冲突 , 在最后提交的时候再进行数据冲突检测 。在乐观锁中,我们有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或者存储过程中 。
不知道这个是不是你需要的...
oracle如何实现行级锁如果当前有用户在对某行数据进行修改登操作,oracle会在这行数据上添加行级锁,期间,所有用户对该行数据只能查询,不可修改,如果比如说执行update操作,需等待该修改操作事务提交或者回滚之后,才行 。
java实现oracle数据库写锁ConnectOracle con = new ConnectOracle();
Connection connect = con.getConnection();
// 设置手动提交事务
connect.setAutoCommit(false);
Statement stmt = connect.createStatement();
// 锁表
stmt.addBatch("lock table t_symbol_code_fee in exclusive mode");
// 此处打上断点后 , 执行另一个类,你会发现 , 执行成功后并没有更改记录,因为表已经被锁定 。只有提交事务后,TestOracle中执行的修改才能生效 。
stmt.executeBatch();
// 提交后自动解锁,回滚时也会自动解锁
connect.commit();
stmt.close();
connect.close();
oracle数据库怎么锁表oracle数据库分行级锁和表级锁 。用select * from table-name for update完成行级锁 。用delete或update完成表级锁 。你锁定的资源 别人会等待你的提交语句或回退语句完成以后再继续进行 。
怎样在oracle 给表加锁??lock table 表名 exclusive mode nowait;-- 锁整个表
select * from 表名 where XXX for update nowaitl -- 锁符合条件的记录
【oracle怎么建锁 oracle 加锁】oracle怎么建锁的介绍就聊到这里吧,感谢你花时间阅读本站内容 , 更多关于oracle 加锁、oracle怎么建锁的信息别忘了在本站进行查找喔 。
推荐阅读
- ios角色扮演rpg游戏,ios角色扮演类游戏
- 怎么查华为手机健康度,华为自查健康
- 本地架设服务器,本地服务器建站
- 原超能飞行队飞机大战游戏,飞行超能力
- C语言清空内存函数实现 c语言清空文件函数
- 华为鸿蒙怎么去除涂鸦,鸿蒙怎么把图库去掉
- 玩射击游戏的老爷爷怎么画,玩射击游戏的老爷爷怎么画图片
- JAVA会议记录管理代码 会议记录管理系统c++课设
- time下载,healthtime下载