- 浏览: 764871 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (258)
- J2SE (18)
- J2EE (33)
- AJAX (4)
- JQuery (1)
- DWR (3)
- Linux/Unix (32)
- PHP (1)
- JSF (8)
- Oracle (34)
- JavaScript (17)
- 批处理 (13)
- ASP (7)
- VBScript (3)
- SqlServer (9)
- Ant (1)
- JDBC (1)
- XML (0)
- MySql (0)
- hibernate (9)
- windows (6)
- .net (0)
- 测试 (2)
- 汇编 (2)
- 网络 (13)
- 其它 (11)
- IDE工具 (6)
- freemarker (4)
- 存储过程 (1)
- 生活 (9)
- python (11)
最新评论
-
d99520y:
hdd unlock我这直接提示can't open driv ...
用PC3000和HDD Unlock解笔记本硬盘密码 -
javaersu:
几个学习Shell的不错网站:shell为您提供了对UNIX系 ...
shell脚本实例 -
zh89233:
一段恶意脚本的分析及思考 -
tiancaicao:
hdd unlock老要联网,一联网就说我这破解不了,让我付费 ...
用PC3000和HDD Unlock解笔记本硬盘密码 -
pythoner126com:
不错,学习了,跟这个作者写的有点像,http://www.yi ...
python对文件进行读写操作
为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突。为了解决这个问题,大多数数据库用的方法就是数据的锁定。
数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁。什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住。而乐观锁就是认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息,让用户决定如何去做。
先从悲观锁开始说。在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=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查询rownum与rowid的不同之处
2010-07-19 16:01 1496以下的文章主要是介 ... -
定时自动操作数据库——Oracle JOB 用法小结
2010-07-19 15:13 1700一、设置初始化参数 job_queue_processes ... -
oracle pl/sql实例练习
2010-07-19 13:27 5464第一部分:oracle pl/sql实例练习(1) 一、使用 ... -
在客户端处理Oracle的数据行加锁问题(select for update)
2010-07-07 14:46 2800数据的完整性和并发性: 在网络数据库处理数据中,需要保证 ... -
查询同一表内多字段同时重复记录的SQL语句
2010-03-17 14:47 1746比如现在有一人员表 ( ... -
Oracle国外站点汇集
2009-09-24 16:52 1236Oracle官方站点 http://www.oracle.co ... -
ORA-01658: 无法为表空间 DATA 中的段创建 INITIAL 区
2009-08-12 22:30 2766ORA-01658: 无法为表空间 DATA 中的段创建 IN ... -
用exp/imp远程操作数据库
2009-08-12 09:34 6205在http://icyheart.iteye.com/blog ... -
oracle中归档模式与非归档模式之间的转换
2009-08-11 15:53 1139如果目前你的数据库处于未打开状态,那么请执行: 在" ... -
ORA-00265: 要求实例恢复, 无法设置 ARCHIVELOG 模式的解决方法
2009-08-11 15:52 2051在进行模式转换的时候会出现" ORA-00265: ... -
一个奇怪的现象
2009-08-07 17:58 1245在sql server和oracle中有这样一个奇怪的现象: ... -
Oracle 函数大全
2009-08-07 12:37 1072备用,以后用的着 -
ORACLE 系统函数与SQLSERVER系统函数的异同
2009-08-07 12:36 1419自己做了个pdf用以将知识更好的归纳 下载地址 -
oracle中以dba_、user_、v$_、all_、session_、index_开头的常用表和视图
2009-08-03 15:06 4994dba_开头 dba_users 数据库用户信息 ... -
oracle实例中5个后台进程的执行顺序
2009-07-31 10:33 1229最近在学oracle当看到5个后台进程(SMON,PMON,L ... -
Oracle实例
2009-07-31 09:34 2279Oracle实例(instance)是一种访问数据库的机制,它 ... -
让MySql插入中文字符
2008-09-24 17:14 1020让MySql插入中文字符,改两个地方即可。首先,在MySql的 ... -
start with ...connect by的用法
2009-06-23 15:51 1184Start with...Connect By子句 ... -
ORA-12514 监听程序当前无法识别连接描述符中的服务
2009-07-30 14:32 2520今天在用oracle的时候遇到了这样一个问题:"OR ... -
七种数据库中Select Top的用法
2009-07-30 11:53 1270Select Top在不同数据库中 ...
相关推荐
详细介绍了Oracle中乐观锁、悲观锁的原理及应用,并有实例
hibernate的乐观锁和悲观锁,两种锁搞定一切
该文档详述ORACLE悲观锁和乐观锁的使用,锁定策略的选择及ORACLE在处理锁升级所使用的锁定转换策略
NULL 博文链接:https://ldd600.iteye.com/blog/534032
什么是锁? 锁定问题 丢失更新 悲观锁定 乐观锁定 乐观锁定还是悲观锁定? 阻塞 死锁 锁升级
从就业与择业的角度来讲,计算机相关专业的大学生从事oracle方面的技术是职业发展中的最佳选择。 其一、就业面广:全球前100强企业99家都在使用ORACLE相关技术,中国政府机构,大中型企事业单位都能有ORACLE技术的...
数据库并发操作,悲观锁和乐观锁
分布式锁三种实现方式: 1. 基于数据库实现分布式锁; 2. 基于缓存(Redis等)实现...所谓乐观锁与前边最大区别在于基于CAS思想,是不具有互斥性,不会产生锁等待而消耗资源,操作过程中认为不存在并发冲突,只有upd
6.2.4 乐观锁定还是悲观锁定? 197 6.2.5 阻塞 198 6.2.6 死锁 201 6.2.7 锁升级 206 6.3 锁类型 206 6.3.1 DML锁 207 6.3.2 DDL锁 215 6.3.3 闩 218 6.3.4 手动锁定和用户定义锁 226 6.4 小结 227 第7章 ...
1.3.6 DBA与开发人员的关系.........................................................119 1.4 小结....................................................................................121 第 2章体系结构概述...
悲观锁 乐观锁 行级锁 分布式锁 分区排队 一致性 一致性算法 paxos zab nwr raft gossip 柔性事务(TCC) 一致性原理 CAP BASE 中间件 数据库 mysql 存储引擎 索引 锁 oracle db2 缓存 ...
new oracle.jdbc.driver.OracleDriver(); DriverManager.registerDriver(driver); 3.加虚拟机参数jdbc.drivers -Djdbc.drivers=oracle.jdbc.driver.OracleDriver 4.从Jdk6.0以后要求,JDBC 4.0 Drivers ...
{1.4.1}整数与浮点数}{23}{subsection.1.4.1} {1.4.1.1}浮点数原理}{24}{subsubsection.1.4.1.1} {1.4.2}格式化输出浮点数}{24}{subsection.1.4.2} {1.4.3}\texttt {char}}{24}{subsection.1.4.3} {1.4.4}转义...