??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲乱码一二三四区乱码,综合偷自拍亚洲乱中文字幕,亚洲乱码av中文一区二区http://m.tkk7.com/conans/category/32946.html你越挣扎我就兴?/description>zh-cnTue, 23 Nov 2010 21:10:17 GMTTue, 23 Nov 2010 21:10:17 GMT60MySQL HandlerSocket in Actionhttp://m.tkk7.com/conans/articles/338499.htmlCONANCONANFri, 19 Nov 2010 10:02:00 GMThttp://m.tkk7.com/conans/articles/338499.html阅读全文

CONAN 2010-11-19 18:02 发表评论
]]>
解决Oracle EM q问题http://m.tkk7.com/conans/articles/287776.htmlCONANCONANTue, 21 Jul 2009 13:36:00 GMThttp://m.tkk7.com/conans/articles/287776.htmlOracle 10g提供?jin)一个基?/span>Web的管理工?/span>EMQ?/span>Enterprise ManagerQ,使用比较方便。不q,如果(zhn)用的是中?/span>Linux环境Q而在安装Oracle的时候,没有加上体中文语a的话Q那登陆Ӟ可能?x)发C文按钮都是类?/span>"□□"字样的ؕ码。下面就是解册问题的方法?/span>
    
该方法适合U旗Asianux 2.0?/span>3.0{操作系l环境?/span>

一、故障问?/span>
打开http://ip:1158/emӞ看到如下的显C,其中中文字符部分是ؕ码:(x)


二、解决问?/span>
1、改?/span>$ORACLE_HOME/jdk目录下的jre的默认字?/span>

# su - oracle
$ cd $ORACLE_HOME/jdk/jre/lib/
$ ls font*zh_CN*


其中Q?/span>font.properties是默认用的字体。还可以看到font.properties.zh_CN.Redhat和其它的字体?/span>

$ cp font.properties font.properties.bak
$ cp font.properties.zh_CN.Redhat font.properties


2、改?/span>$ORACLE_HOME/jre下的默认字体
使用上面同样的方法来操作?/span>

$ cd $ORACLE_HOME/jre/1.4.2/lib/
$ ls font*zh_CN*
$ cp font.properties font.properties.bak
$ cp font.properties.zh_CN.Redhat font.properties


3、删?/span>Cache下的gif文g
em
里面?x)用到这些图片?x)

$ cd $ORACLE_HOME/oc4j/j2ee/oc4j_applications/\
applications/em/em/cabo/images/cache/zhs/
$ ls *.gif
$ rm *.gif


?/span> 注意不要搞错目录Q修改的是中文环境的?/span>

4、重新启?/span>EM服务

$ emctl stop dbconsole
$ emctl start dbconsole


q入EM看看中文问题是否已经解决?/span>

新打开的界面如下:(x)



CONAN 2009-07-21 21:36 发表评论
]]>
Linux下Oracle 10G DBCA{汉字ؕ码解x?/title><link>http://m.tkk7.com/conans/articles/287532.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Mon, 20 Jul 2009 13:55:00 GMT</pubDate><guid>http://m.tkk7.com/conans/articles/287532.html</guid><description><![CDATA[<p><font id="zoom" class="zw_txt">Linux下Oracle 10G DBCA{汉字ؕ码的解决Ҏ(gu)其实很简单:(x)</font></p> <p><font id="zoom" class="zw_txt">1、在Linux下安装新的JDKQJREQ,我装的是1.6Q?/font></p> <p><font id="zoom" class="zw_txt">2、修改DBCA所对应的JRE路径Q默认下/u01/app/oralce/product/10.2.0/db_1/bin/dbcaQ?/font></p> <font id="zoom" class="zw_txt">3、完成(em修改同理Q?/font> <img src ="http://m.tkk7.com/conans/aggbug/287532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/conans/" target="_blank">CONAN</a> 2009-07-20 21:55 <a href="http://m.tkk7.com/conans/articles/287532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>提高MySQL 数据库性能的思\ http://m.tkk7.com/conans/articles/214464.htmlCONANCONANSat, 12 Jul 2008 11:16:00 GMThttp://m.tkk7.com/conans/articles/214464.html
       1、选取最适用的字D属?

  MySQL可以很好的支持大数据量的存取Q但是一般说来,数据库中的表小Q在它上面执行的查询也就?x)越快。因此,在创的时候,Z(jin)获得更好的性能Q我们可以将表中字段的宽度设得尽可能。例如,在定义邮政编码这个字D|Q如果将其设|ؓ(f)CHAR(255),昄l数据库增加?jin)不必要的空_(d)甚至使用VARCHARq种cd也是多余的,因ؓ(f)CHAR(6)可以很好的完成d?jin)。同L(fng)Q如果可以的话,我们应该使用MEDIUMINT而不是BIGIN来定义整型字Dc(din)?

  另外一个提高效率的Ҏ(gu)是在可能的情况下Q应该尽量把字段讄为NOT NULLQ这样在来执行查询的时候,数据库不用去比较NULL倹{?

  对于某些文本字段Q例?#8220;省䆾”或?#8220;性别”Q我们可以将它们定义为ENUMcd。因为在MySQL中,ENUMcd被当作数值型数据来处理,而数值型数据被处理v来的速度要比文本cd快得多。这P我们又可以提高数据库的性能?

  2、用连接(JOINQ来代替子查?Sub-Queries)

  MySQL?.1开始支持SQL的子查询。这个技术可以用SELECT语句来创Z个单列的查询l果Q然后把q个l果作ؓ(f)qo(h)条g用在另一个查询中。例如,我们要将客户基本信息表中没有M订单的客户删除掉Q就可以利用子查询先从销售信息表中将所有发?gu)单的客户ID取出来,然后结果传递给L询,如下所C:(x)

DELETE FROM customerinfo
WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )

  使用子查询可以一ơ性的完成很多逻辑上需要多个步骤才能完成的SQL操作Q同时也可以避免事务或者表锁死Qƈ且写h也很Ҏ(gu)。但是,有些情况下,子查询可以被更有效率的连接(JOINQ?. 替代。例如,假设我们要将所有没有订单记录的用户取出来,可以用下面这个查询完成:(x)

SELECT * FROM customerinfo
WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )

  如果使用q接QJOINQ?. 来完成这个查询工作,速度会(x)快很多。尤其是当salesinfo表中对CustomerID建有索引的话Q性能会(x)更好Q查询如下:(x)

SELECT * FROM customerinfo
LEFT JOIN salesinfoON customerinfo.CustomerID=salesinfo.
CustomerID
WHERE salesinfo.CustomerID IS NULL

 q接QJOINQ?. 之所以更有效率一些,是因?MySQL不需要在内存中创Z(f)时表来完成这个逻辑上的需要两个步骤的查询工作?

  3、用联?UNION)来代替手动创建的临时?/strong>

  MySQL ?4.0 的版本开始支?UNION 查询Q它可以把需要用(f)时表的两条或更多?SELECT 查询合ƈ的一个查询中。在客户端的查询?x)话l束的时候,临时表会(x)被自动删除,从而保证数据库整齐、高效。?UNION 来创建查询的时候,我们只需要用 UNION作ؓ(f)关键字把多个 SELECT 语句q接h可以了(jin)Q要注意的是所?SELECT 语句中的字段数目要想同。下面的例子演CZ(jin)一个?UNION的查询?

SELECT Name, Phone FROM client
UNION
SELECT Name, BirthDate FROM author
UNION
SELECT Name, Supplier FROM product

  4、事?/strong>

  管我们可以使用子查询(Sub-QueriesQ、连接(JOINQ和联合QUNIONQ来创徏各种各样的查询,但不是所有的数据库操作都可以只用一条或数几条SQL语句可以完成的。更多的时候是需要用Cpd的语句来完成某种工作。但是在q种情况下,当这个语句块中的某一条语句运行出错的时候,整个语句块的操作׃(x)变得不确定v来。设想一下,要把某个数据同时插入两个相关联的表中Q可能会(x)出现q样的情况:(x)W一个表中成功更新后Q数据库H然出现意外状况Q造成W二个表中的操作没有完成Q这P׃(x)造成数据的不完整Q甚至会(x)破坏数据库中的数据。要避免q种情况Q就应该使用事务Q它的作用是Q要么语句块中每条语句都操作成功Q要么都p|。换句话_(d)是可以保持数据库中数据的一致性和完整性。事物以BEGIN 关键字开始,COMMIT关键字结束。在q之间的一条SQL操作p|Q那么,ROLLBACK命o(h)可以把数据库恢复到BEGIN开始之前的状态?

BEGIN;
INSERT INTO salesinfo SET CustomerID=14;
UPDATE inventory SET Quantity=11
WHERE item='book';
COMMIT;

  事务的另一个重要作用是当多个用户同时用相同的数据源时Q它可以利用锁定数据库的Ҏ(gu)来ؓ(f)用户提供一U安全的讉K方式Q这样可以保证用L(fng)操作不被其它的用hq扰?

  5、锁定表

  管事务是维护数据库完整性的一个非常好的方法,但却因ؓ(f)它的独占性,有时?x)?jing)响数据库的性能Q尤其是在很大的应用pȝ中。由于在事务执行的过E中Q数据库会(x)被锁定,因此其它的用戯求只能暂时等待直到该事务l束。如果一个数据库pȝ只有数几个用户
来用,事务造成的媄(jing)响不?x)成Z个太大的问题Q但假设有成千上万的用户同时讉K一个数据库pȝQ例如访问一个电(sh)子商务网站,׃(x)产生比较严重的响应gq?

  其实Q有些情况下我们可以通过锁定表的Ҏ(gu)来获得更好的性能。下面的例子q锁定表的Ҏ(gu)来完成前面一个例子中事务的功能?

LOCK TABLE inventory WRITE
SELECT Quantity FROM inventory
WHEREItem='book';
...
UPDATE inventory SET Quantity=11
WHEREItem='book';
UNLOCK TABLES

  q里Q我们用一?SELECT 语句取出初始数据Q通过一些计,?UPDATE 语句新值更新到表中。包含有 WRITE 关键字的 LOCK TABLE 语句可以保证?UNLOCK TABLES 命o(h)被执行之前,不会(x)有其它的讉K来对 inventory q行插入、更新或者删除的操作?

  6、用外?/strong>

  锁定表的Ҏ(gu)可以l护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。例如,外键可以保证每一条销售记录都指向某一个存在的客户。在q里Q外键可以把customerinfo 表中的CustomerID映射到salesinfo表中CustomerIDQQ何一条没有合法CustomerID的记录都不会(x)被更新或插入到salesinfo中?

CREATE TABLE customerinfo
(
CustomerID INT NOT NULL ,
PRIMARY KEY ( CustomerID )
) TYPE = INNODB;

CREATE TABLE salesinfo
(
SalesID INT NOT NULL,
CustomerID INT NOT NULL,
PRIMARY KEY(CustomerID, SalesID),
FOREIGN KEY (CustomerID) REFERENCES customerinfo
(CustomerID) ON DELETECASCADE
) TYPE = INNODB;

  注意例子中的参数“ON DELETE CASCADE”。该参数保证?customerinfo 表中的一条客戯录被删除的时候,salesinfo 表中所有与该客L(fng)关的记录也会(x)被自动删除。如果要?MySQL 中用外键,一定要C在创的时候将表的cd定义Z务安全表 InnoDBcd。该cd不是 MySQL 表的默认cd。定义的Ҏ(gu)是在 CREATE TABLE 语句中加?TYPE=INNODB。如例中所C?

  7、用烦(ch)?/strong>

  索引是提高数据库性能的常用方法,它可以o(h)数据库服务器以比没有索引快得多的速度(g)索特定的行,其是在查询语句当中包含有MAX(), MIN()和ORDERBYq些命o(h)的时候,性能提高更ؓ(f)明显。那该对哪些字段建立索引呢?一般说来,索引应徏立在那些用于JOIN, WHERE判断和ORDER BY排序的字D上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。对于一个ENUMcd的字D|_(d)出现大量重复值是很有可能的情况,例如customerinfo中的“province”.. 字段Q在q样的字D上建立索引不?x)有什么帮助;相反Q还有可能降低数据库的性能。我们在创徏表的时候可以同时创建合适的索引Q也可以使用ALTER TABLE或CREATE INDEX在以后创建烦(ch)引。此外,MySQL
从版?.23.23开始支持全文烦(ch)引和搜烦(ch)。全文烦(ch)引在MySQL 中是一个FULLTEXTcd索引Q但仅能用于MyISAM cd的表。对于一个大的数据库Q将数据装蝲C个没有FULLTEXT索引的表中,然后再用ALTER TABLE或CREATE INDEX创徏索引Q将是非常快的。但如果数据装载到一个已l有FULLTEXT索引的表中,执行q程会(x)非常慢?

  8、优化的查询语句

  l大多数情况下,使用索引可以提高查询的速度Q但如果SQL语句使用不恰当的话,索引无法发挥它应有的作用。下面是应该注意的几个方面。首先,最好是在相同类型的字段间进行比较的操作。在MySQL 3.23版之前,q甚x一个必ȝ条g。例如不能将一个徏有烦(ch)引的INT字段和BIGINT字段q行比较Q但是作为特D的情况Q在CHARcd的字D和VARCHARcd字段的字D大相同的时候,可以它们进行比较。其ơ,在徏有烦(ch)引的字段上尽量不要用函数进行操作?

  例如Q在一个DATEcd的字D上使用YEAE()函数Ӟ会(x)使烦(ch)引不能发挥应有的作用。所以,下面的两个查询虽然返回的l果一P但后者要比前者快得多?

SELECT * FROM order WHERE YEAR(OrderDate)<2001;

SELECT * FROM order WHERE OrderDate<"2001-01-01";

同样的情形也?x)发生在?gu)值型字段q行计算的时候:(x)

SELECT * FROM inventory WHERE Amount/7<24;

SELECT * FROM inventory WHERE Amount<24*7;

  上面的两个查询也是返回相同的l果Q但后面的查询将比前面的一个快很多。第三,在搜索字W型字段Ӟ我们有时?x)?LIKE 关键字和通配W,q种做法虽然单,但却也是以牺牲系l性能ZL(fng)。例如下面的查询会(x)比较表中的每一条记录?

SELECT * FROM books
WHERE name like "MySQL%"

  但是如果换用下面的查询,q回的结果一P但速度p快上很多Q?

SELECT * FROM books
WHERE name>="MySQL"and name<"MySQM"

  最后,应该注意避免在查询中让MySQLq行自动cd转换Q因{换过E也?x)索引变得不v作用?

CONAN 2008-07-12 19:16 发表评论
]]>
Oracle10g SCN机制http://m.tkk7.com/conans/articles/214086.htmlCONANCONANThu, 10 Jul 2008 11:26:00 GMThttp://m.tkk7.com/conans/articles/214086.html
中科院信息工E硕士学位,分别在深圛_为、北京兆l?q和4q的工作l验Q主要负责IT开发和企业解决Ҏ(gu)Q包括项目管理、设计、实施在IT基础架构?qing)SOA解决Ҏ(gu)领域Q在仓储物流、零售业RFID应用、旅游及(qing)?sh)子商务领域有实际工作经验?


SCNQSystem Chang NumberQ作为oracle中的一个重要机Ӟ在数据恢复、Data Guard、Streams复制、RAC节点间的同步{各个功能中L(fng)重要作用。理解SCN的运作机Ӟ可以帮助你更加深入地?jin)解上述功能?/span>

在理解SCN之前Q我们先看下oracle事务中的数据变化是如何写入数据文件的Q?/span>
 
1、事务开始;
2、在buffer cache中找到需要的数据块,如果没有扑ֈQ则从数据文件中载入buffer cache中;
3、事务修改buffer cache的数据块Q该数据被标识ؓ(f)“脏数?#8221;Qƈ被写入log buffer中;
4、事务提交,LGWRq程log buffer中的“脏数?#8221;写入redo log file中;
5、当发生checkpointQCKPTq程更新所有数据文件的文g头中的信息,DBWnq程则负责将Buffer Cache中的脏数据写入到数据文g中?/span>
 
l过上述5个步骤,事务中的数据变化最l被写入到数据文件中。但是,一旦在上述中间环节Ӟ数据库意外宕Z(jin)Q在重新启动时如何知道哪些数据已l写入数据文件、哪些没有写呢(同样Q在DG、streams中也存在cM疑问Qredo log中哪些是上一ơ同步已l复制过的数据、哪些没有)(j)QSCN机制p比较完善的解决上q问题?/span>
 
SCN是一个数字,切的说是一个只?x)增加、不?x)减的数字。正是它q种只会(x)增加的特性确保了(jin)Oracle知道哪些应该被恢复、哪些应该被复制?/span>
 
d?中SCNQ系l检查点QSystem CheckpointQSCN、数据文件检查点QDatafile CheckpointQSCN、结束SCNQStop SCNQ、开始SCNQStart SCNQ。其中其?中SCN存在于控制文件中Q最后一U则存在于数据文件的文g头中?/span>
在控制文件中QSystem Checkpoint SCN是针Ҏ(gu)个数据库全局的,因而之存在一个,而Datafile Checkpoint SCN和Stop SCN是针Ҏ(gu)个数据文件的Q因而一个数据文件就对应在控制文件中存在一份Datafile Checkpoint SCN和Stop SCN。在数据库正常运行期_(d)Stop SCN(通过视图v$datafile的字Dlast_change#可以查询)是一个无I大的数字或者说是NULL?/span>
 
在一个事务提交后Q上q第四个步骤Q,?x)在redo log中存在一条redo记录Q同Ӟpȝ为其提供一个最新的SCNQ通过函数dbms_flashback.get_system_change_number可以知道当前的最新SCNQ,记录在该条记录中。如果该条记录是在redo log被清I(日志满做切换时或发生checkpointӞ所有变化日志已l被写入数据文g中)(j)Q则其SCN被记录ؓ(f)redo log的low SCN。以后在日志再次被清I前写入的redo记录中SCN则成为Next SCN?/span>
 
当日志切换或发生checkpointQ上q第五个步骤Q时Q从Low SCN到Next SCN之间的所有redo记录的数据就被DBWnq程写入数据文g中,而CKPTq程则将所有数据文Ӟ无论redo log中的数据是否影响到该数据文gQ的文g头上记录的Start SCN(通过视图v$datafile_header的字Dcheckpoint_change#可以查询)更新为Next SCNQ同时将控制文g中的System Checkpoint SCNQ通过视图v$database的字Dcheckpoint_change#可以查询Q、每个数据文件对应的Datafile CheckpointQ通过视图v$datafile的字Dcheckpoint_change#可以查询Q也更新为Next SCN。但是,如果该数据文件所在的表空间被讄为read-onlyӞ数据文g的Start SCN和控制文件中Datafile Checkpoint SCN都不?x)被更新?/span>
 
那系l是如何产生一个最新的SCN的?实际上,q个数字是由当时的timestamp转换q来的。每当需要生一个最新的SCN到redo记录Ӟpȝ获取当时的timestampQ将其{换ؓ(f)数字作ؓ(f)SCN。我们可以通过函数SCN_TO_TIMESTAMPQ?0g以后Q将其{换回timestampQ?/span>
 
SQL> select dbms_flashback.get_system_change_number, SCN_TO_TIMESTAMP(dbms_flashback.get_system_change_number) from dual;
 
GET_SYSTEM_CHANGE_NUMBER
------------------------
SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER)
---------------------------------------------------------------------------
              2877076756
17-AUG-07 02.15.26.000000000 PM
 
也可以用函数timestamp_to_scn一个timestamp转换为SCNQ?/div>
 
SQL> select timestamp_to_scn(SYSTIMESTAMP) as scn from dual;
 
       SCN
----------
2877078439
 
最后,SCN除了(jin)作ؓ(f)反映事务数据变化q保持同步外Q它qv到系l的“?j)?#8221;作用——每?U左右系l会(x)h一ơ系lSCN?/span>
 
下面Q在单介l一下SCN如何在数据库恢复中v作用?/span>
 
数据库在正常关闭Qshutdown immediate/normalQ时Q会(x)先做一ơcheckpointQ将log file中的数据写入数据文g中,控制文件、数据文件中的SCNQ包括控制文件中的Stop SCNQ都更新为最新的SCN?/span>
 
数据库异?意外关闭不会(x)或者只更新部分Stop SCN?/span>
 
当数据库启动ӞOracle先检查控制文件中的每个Datafile Checkpoint SCN和数据文件中的Start SCN是否相同Q再(g)查每个Datafile Checkpoint SCN和Stop SCN是否相同。如果发现有不同Q就从Redo Log中找CqSCNQ重新写入数据文件中q行恢复。具体的数据恢复q程q里׃再赘q?/span>
 
SCN作ؓ(f)Oracle中的一个重要机Ӟ在多个重要功能中L(fng)“控制?#8221;的作用。了(jin)解SCN的生和实现方式Q帮助DBA理解和处理恢复、DG、Streams复制的问题?/span>
 
最后提一句,利用SCN机制Q在Oracle10g?1g中又增加?jin)一些很实用的功能——数据库闪回、数据库负蝲重现{?/span>


CONAN 2008-07-10 19:26 发表评论
]]> 数据库连接池概述http://m.tkk7.com/conans/articles/214083.htmlCONANCONANThu, 10 Jul 2008 11:19:00 GMThttp://m.tkk7.com/conans/articles/214083.html

数据库连接池概述Q?/p>

数据库连接是一U关键的有限的昂늚资源Q这一点在多用L(fng)|页应用E序中体现得ؓ(f)H出。对数据库连接的理能显著媄(jing)响到整个应用E序的׾~性和健壮性,影响到程序的性能指标。数据库q接池正是针对这个问题提出来的?/p>

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复用一个现有的数据库连接,而再不是重新建立一个;释放I闲旉过最大空闲时间的数据库连接来避免因ؓ(f)没有释放数据库连接而引L(fng)数据库连接遗漏。这Ҏ(gu)术能明显提高Ҏ(gu)据库操作的性能?/p>

?据库q接池在初始化时创Z定数量的数据库连接放到连接池中,q些数据库连接的数量是由最数据库q接数来讑֮的。无些数据库q接是否被用,q接 池都一直保证至拥有这么多的连接数量。连接池的最大数据库q接数量限定?jin)这个连接池能占有的最大连接数Q当应用E序向连接池h的连接数过最大连?数量Ӟq些h被加入到等待队列中。数据库q接池的最连接数和最大连接数的设|要考虑C列几个因素:(x)

1) 最连接数是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,会(x)有大量的数据库连接资源被费Q?/p>

2) 最大连接数是连接池能申L(fng)最大连接数Q如果数据库q接h过此数Q后面的数据库连接请求将被加入到{待队列中,q会(x)影响之后的数据库操作?/p>

3) 如果最连接数与最大连接数相差太大Q那么最先的q接h会(x)获利Q之后超q最连接数量的q接h{h(hun)于徏立一个新的数据库q接。不q,q些大于最连接数的数据库q接在用完不会(x)马上被释放,它将被放到连接池中等待重复用或是空闲超时后被释放?/p>



CONAN 2008-07-10 19:19 发表评论
]]>
数据库中乐观锁与(zhn)观锁的概念http://m.tkk7.com/conans/articles/214081.htmlCONANCONANThu, 10 Jul 2008 11:18:00 GMThttp://m.tkk7.com/conans/articles/214081.html

锁( locking Q?/p>

业务逻辑的实现过E中Q往往需要保证数据访问的排他性。如在金融系l的日终l算

处理中,我们希望针对某个 cut-off 旉点的数据q行处理Q而不希望在结进行过E中

Q可能是几秒U,也可能是几个时Q,数据再发生变化。此Ӟ我们需要通过一些机

制来保证q些数据在某个操作过E中不会(x)被外界修改,q样的机Ӟ在这里,也就是所?/p>

?“ ?” Q即l我们选定的目标数据上锁,使其无法被其他程序修攏V?/p>

Hibernate 支持两种锁机Ӟ(x)即通常所说的 “ (zhn)观锁( Pessimistic Locking Q?”

?“ 乐观锁( Optimistic Locking Q?” ?/p>

(zhn)观锁( Pessimistic Locking Q?/p>

(zhn)观锁,正如其名Q它指的是对数据被外界(包括本系l当前的其他事务Q以?qing)来?/p>

外部pȝ的事务处理)(j)修改持保守态度Q因此,在整个数据处理过E中Q将数据处于锁定

状态。?zhn)观锁的实玎ͼ往往依靠数据库提供的锁机Ӟ也只有数据库层提供的锁机制才?/p>

真正保证数据讉K的排他性,否则Q即使在本系l中实现?jin)加锁机Ӟ也无法保证外部?/p>

l不?x)修?gu)据)(j)?/p>

一个典型的倚赖数据库的(zhn)观锁调用:(x)

select * from account where name=”Erica” for update

q条 sql 语句锁定?account 表中所有符合检索条Ӟ name=”Erica” Q的记录?/p>

本次事务提交之前Q事务提交时?x)释放事务过E中的锁Q,外界无法修改q些记录?/p>

Hibernate 的?zhn)观锁Q也是基于数据库的锁机制实现?/p>

注意Q只有在查询开始之前(也就?Hiberate 生成 SQL 之前Q设定加锁,才会(x)

真正通过数据库的锁机制进行加锁处理,否则Q数据已l通过不包?for update

子句?Select SQL 加蝲q来Q所谓数据库加锁也就无从谈v?/p>

乐观锁( Optimistic Locking Q?/p>

相对(zhn)观锁而言Q乐观锁机制采取?jin)更加宽杄加锁机制。?zhn)观锁大多数情况下?/p>

靠数据库的锁机制实现Q以保证操作最大程度的独占性。但随之而来的就是数据库

性能的大量开销Q特别是寚w事务而言Q这L(fng)开销往往无法承受?/p>

如一个金融系l,当某个操作员d用户的数据,q在d的用h据的基础上进

行修Ҏ(gu)Q如更改用户帐户余额Q,如果采用(zhn)观锁机Ӟ也就意味着整个操作q?/p>

E中Q从操作员读出数据、开始修改直x交修改结果的全过E,甚至q包括操?/p>

员中途去煮咖啡的旉Q,数据库记录始l处于加锁状态,可以惌Q如果面对几

百上千个q发Q这L(fng)情况导致怎样的后果?/p>

乐观锁机制在一定程度上解决?jin)这个问题。乐观锁Q大多是Z数据版本

Q?Version Q记录机制实现。何谓数据版本?即ؓ(f)数据增加一个版本标识,在基?/p>

数据库表的版本解x案中Q一般是通过为数据库表增加一?“version” 字段?/p>

实现?/p>

d出数据时Q将此版本号一同读出,之后更新ӞҎ(gu)版本号加一。此Ӟ提

交数据的版本数据与数据库表对应记录的当前版本信息q行比对Q如果提交的数据

版本号大于数据库表当前版本号Q则予以更新Q否则认为是q期数据?/p>

对于上面修改用户帐户信息的例子而言Q假设数据库中帐户信息表中有一?/p>

version 字段Q当前gؓ(f) 1 Q而当前帐户余额字D( balance Qؓ(f) $100 ?/p>

1 操作?A 此时其dQ?version=1 Q,q从其帐户余额中扣除 $50

Q?$100-$50 Q?/p>

2 在操作员 A 操作的过E中Q操作员 B 也读入此用户信息Q?version=1 Q,q?/p>

从其帐户余额中扣?$20 Q?$100-$20 Q?/p>

3 操作?A 完成?jin)修改工作,数据版本号加一Q?version=2 Q,q同帐户?/p>

除后余额Q?balance=$50 Q,提交x据库更新Q此时由于提交数据版本大

于数据库记录当前版本Q数据被更新Q数据库记录 version 更新?2 ?/p>

4 操作?B 完成?jin)操作,也将版本号加一Q?version=2 Q试囑֐数据库提交数

据( balance=$80 Q,但此时比Ҏ(gu)据库记录版本时发玎ͼ操作?B 提交?/p>

数据版本号ؓ(f) 2 Q数据库记录当前版本也ؓ(f) 2 Q不满 “ 提交版本必须大于?/p>

录当前版本才能执行更?“ 的乐观锁{略Q因此,操作?B 的提交被驛_?/p>

q样Q就避免?jin)操作?B 用基?version=1 的旧数据修改的结果覆盖操?/p>

?A 的操作结果的可能?/p>

从上面的例子可以看出Q乐观锁机制避免?jin)长事务中的数据库加锁开销Q操作员 A

和操作员 B 操作q程中,都没有对数据库数据加锁)(j)Q大大提升了(jin)大ƈ发量下的p?/p>

l整体性能表现?/p>

需要注意的是,乐观锁机制往往Zpȝ中的数据存储逻辑Q因此也具备一定的局

限性,如在上例中,׃乐观锁机制是在我们的pȝ中实玎ͼ来自外部pȝ的用?/p>

余额更新操作不受我们pȝ的控Ӟ因此可能?x)造成脏数据被更新到数据库中。在

pȝ设计阶段Q我们应该充分考虑到这些情况出现的可能性,q进行相应调_(d)?/p>

乐观锁{略在数据库存储q程中实玎ͼ对外只开攑֟于此存储q程的数据更新?/p>

径,而不是将数据库表直接对外公开Q?/p>



CONAN 2008-07-10 19:18 发表评论
]]>
վ֩ģ壺 aëƬѸƵ| ŷۺ| ɫվWWW| ĻAëƬ| þô| 7723ձ| Ļɫͼ| 88avѹۿ| һƬaѲſ֮| ŷպĻһ | ȫԼƵ| ҹɫ˽ӰԺվ| һƵ߹ۿ| Ƶһ| Ʒһֱ| һѹۿ | һƵ| þԭavapp| 99þ99þþƷѿ| Ʒۺ| 鶹Ʒѹۿ| ƵѹۿƵ| þþþŮۺ| ޹99Ʒ| ŮƵ77777| վѹۿ| avŮӰ| ߲˳Ƶ߹ۿ| ޾ƷŮ| ޴ɫƵ| վ| j8ֳִӲˬƵ| þ޹| 椸Ƶ߹ۿ| һһһƬѸ| ޾Ʒѿ| Ѵѧ߹ۿp| aëƬѿ| ˳ɫ77777߹ۿ| ޹ۺһ| Ů18ëƬؼһƵ|