﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-微笑沙漠-随笔分类-Hibernate</title><link>http://www.blogjava.net/cyantide/category/42012.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 09 Oct 2009 03:00:28 GMT</lastBuildDate><pubDate>Fri, 09 Oct 2009 03:00:28 GMT</pubDate><ttl>60</ttl><item><title>Hibernate 锁 转帖</title><link>http://www.blogjava.net/cyantide/archive/2009/10/09/297510.html</link><dc:creator>微笑沙漠</dc:creator><author>微笑沙漠</author><pubDate>Fri, 09 Oct 2009 02:30:00 GMT</pubDate><guid>http://www.blogjava.net/cyantide/archive/2009/10/09/297510.html</guid><wfw:comment>http://www.blogjava.net/cyantide/comments/297510.html</wfw:comment><comments>http://www.blogjava.net/cyantide/archive/2009/10/09/297510.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cyantide/comments/commentRss/297510.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyantide/services/trackbacks/297510.html</trackback:ping><description><![CDATA[hibernate锁机制包括悲观锁和乐观锁<br />
<br />
1.悲观锁：<br />
<br />
它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时，都可能有另一个客户也正在存取同一笔数据，为了保持数据被操作的一致性，于是对数据采取了<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="baidusnap1"></a><strong style="color: black; background-color: #a0ffff;">数据库</strong>层次的<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="baidusnap0"></a><strong style="color: black; background-color: #ffff66;">锁定</strong>状态，依靠<strong style="color: black; background-color: #a0ffff;">数据库</strong>提供的锁机制来实现。<br />
<br />
基于jdbc实现的<strong style="color: black; background-color: #a0ffff;">数据库</strong>加锁如下：<br />
<br />
select * from account where name="Erica" for update.在更新的过程中，<strong style="color: black; background-color: #a0ffff;">数据库</strong>处于加锁状态，任何其他的针对本条数据的操作都将被延迟。本次事务提交后<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="baidusnap3"></a><strong style="color: black; background-color: #ff9999;">解锁</strong>。<br />
<br />
而hibernate悲观锁的具体实现如下：<br />
<br />
String sql="查询语句";<br />
Query query=session.createQuery(sql);<br />
query.setLockMode("对象"，LockModel.UPGRADE);<br />
<br />
说到这里，就提到了hiernate的加锁模式：<br />
<br />
LockMode.NONE ： 无锁机制。<br />
LockMode.WRITE ：Hibernate在Insert和Update记录的时候会自动获取。<br />
LockMode.READ ： Hibernate在读取记录的时候会自动获取。<br />
<br />
这三种加锁模式是供hibernate内部使用的，与<strong style="color: black; background-color: #a0ffff;">数据库</strong>加锁无关<br />
<br />
LockMode.UPGRADE：利用<strong style="color: black; background-color: #a0ffff;">数据库</strong>的for update字句加锁。<br />
<br />
在这里我们要注意的是：只有在查询开始之前（也就是hiernate生成sql语句之前）加锁，才会真正通过<strong style="color: black; background-color: #a0ffff;">数据库</strong>的锁机制加锁处理。否则，数据已经通过不包含for updata子句的sql语句加载进来，所谓的<strong style="color: black; background-color: #a0ffff;">数据库</strong>加锁也就无从谈起。<br />
<br />
但是，从系统的性能上来考虑，对于单机或小系统而言，这并不成问题，然而如果是在网络上的系统，同时间会有许多联机，假设有数以百计或上千甚至更多的并发访问出现，我们该怎么办？如果等到<strong style="color: black; background-color: #a0ffff;">数据库</strong><strong style="color: black; background-color: #ff9999;">解锁</strong>我们再进行下面的操作，我们浪费的资源是多少？--这也就导致了乐观锁的产生。<br />
<br />
2.乐观锁：<br />
<br />
乐观<strong style="color: black; background-color: #ffff66;">锁定</strong>（optimistic locking）则乐观的认为资料的存取很少发生同时存取的问题，因而不作<strong style="color: black; background-color: #a0ffff;">数据库</strong>层次上的<strong style="color: black; background-color: #ffff66;">锁定</strong>，为了维护正确的数据，乐观<strong style="color: black; background-color: #ffff66;">锁定</strong>采用应用程序上的逻辑实现版本控制的方法。<br />
<br />
例如若有两个客户端，A客户先读取了账户余额100元，之后B客户也读取了账户余额100元的数据，A客户提取了50元，对<strong style="color: black; background-color: #a0ffff;">数据库</strong>作了变更，此时<strong style="color: black; background-color: #a0ffff;">数据库</strong>中的余额为50元，B客户也要提取30元，根据其所取得的资料，100-30将为70余额，若此时再对<strong style="color: black; background-color: #a0ffff;">数据库</strong>进行变更，最后的余额就会不正确。<br />
<br />
在不实行悲观<strong style="color: black; background-color: #ffff66;">锁定</strong>策略的情况下，数据不一致的情况一但发生，有几个解决的方法，一种是先更新为主，一种是后更新的为主，比较复杂的就是检查发生变动的数据来实现，或是检查所有属性来实现乐观<strong style="color: black; background-color: #ffff66;">锁定</strong>。<br />
<br />
Hibernate 中透过版本号检查来实现后更新为主，这也是Hibernate所推荐的方式，在<strong style="color: black; background-color: #a0ffff;">数据库</strong>中加入一个VERSON栏记录，在读取数据时连同版本号一同读取，并在更新数据时递增版本号，然后比对版本号与<strong style="color: black; background-color: #a0ffff;">数据库</strong>中的版本号，如果大于<strong style="color: black; background-color: #a0ffff;">数据库</strong>中的版本号则予以更新，否则就回报错误。<br />
<br />
以刚才的例子，A客户读取账户余额1000元，并连带读取版本号为5的话，B客户此时也读取账号余额1000元，版本号也为5，A客户在领款后账户余额为500，此时将版本号加1，版本号目前为6，而<strong style="color: black; background-color: #a0ffff;">数据库</strong>中版本号为5，所以予以更新，更新<strong style="color: black; background-color: #a0ffff;">数据库</strong>后，<strong style="color: black; background-color: #a0ffff;">数据库</strong>此时余额为500，版本号为6，B客户领款后要变更<strong style="color: black; background-color: #a0ffff;">数据库</strong>，其版本号为5，但是<strong style="color: black; background-color: #a0ffff;">数据库</strong>的版本号为6，此时不予更新，B客户数据重新读取<strong style="color: black; background-color: #a0ffff;">数据库</strong>中新的数据并重新进行业务流程才变更<strong style="color: black; background-color: #a0ffff;">数据库</strong>。<br />
<br />
以Hibernate实现版本号控制<strong style="color: black; background-color: #ffff66;">锁定</strong>的话，我们的对象中增加一个version属性，例如：<br />
<br />
<p class="code">&lt;public&nbsp;class&nbsp;Account&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;int&nbsp;version;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;....<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;setVersion(int&nbsp;version)&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.version&nbsp;=&nbsp;version;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;getVersion()&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;version;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;....<br />
<br />
}<br />
</p>
<br />
而在映像文件中，我们使用optimistic-lock属性设定version控制，&lt;id&gt;属性栏之后增加一个&lt;version&gt;标签，如下：<br />
<br />
<p class="code">&lt;hibernate-mapping&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;class&nbsp;name="onlyfun.caterpillar.Account"&nbsp;talble="ACCOUNT"<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;optimistic-lock="version"&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;id...../&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;version&nbsp;name="version"&nbsp;column="VERSION"/&gt;<br />
<br />
&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;....<br />
<br />
&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/class&gt;<br />
<br />
&lt;/hibernate-mapping&gt;<br />
</p>
<br />
设定好版本控制之后，在上例中如果B 客户试图更新数据，将会引发StableObjectStateException例外，我们可以捕捉这个例外，在处理中重新读取<strong style="color: black; background-color: #a0ffff;">数据库</strong>中的数据，同时将 B客户目前的数据与<strong style="color: black; background-color: #a0ffff;">数据库</strong>中的数据秀出来，让B客户有机会比对不一致的数据，以决定要变更的部份，或者您可以设计程式自动读取新的资料，并重复扣款业务流程，直到数据可以更新为止，这一切可以在背景执行，而不用让您的客户知道。<br />
<br />
但是乐观锁也有不能解决的问题存在：上面已经提到过乐观锁机制的实现往往基于系统中的数据存储逻辑，在我们的系统中实现，来自外部系统的用户余额更新不受我们系统的控制，有可能造成非法数据被更新至<strong style="color: black; background-color: #a0ffff;">数据库</strong>。因此我们在做电子商务的时候，一定要小心的注意这项存在的问题，采用比较合理的逻辑验证，避免数据执行错误。<br />
<br />
也可以在使用Session的load()或是lock()时指定<strong style="color: black; background-color: #ffff66;">锁定</strong>模式以进行<strong style="color: black; background-color: #ffff66;">锁定</strong>。<br />
<br />
如果<strong style="color: black; background-color: #a0ffff;">数据库</strong>不支持所指定的<strong style="color: black; background-color: #ffff66;">锁定</strong>模式，Hibernate会选择一个合适的<strong style="color: black; background-color: #ffff66;">锁定</strong>替换，而不是丢出一个例外。
<img src ="http://www.blogjava.net/cyantide/aggbug/297510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyantide/" target="_blank">微笑沙漠</a> 2009-10-09 10:30 <a href="http://www.blogjava.net/cyantide/archive/2009/10/09/297510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate 锁机制 转帖</title><link>http://www.blogjava.net/cyantide/archive/2009/10/09/297509.html</link><dc:creator>微笑沙漠</dc:creator><author>微笑沙漠</author><pubDate>Fri, 09 Oct 2009 02:29:00 GMT</pubDate><guid>http://www.blogjava.net/cyantide/archive/2009/10/09/297509.html</guid><wfw:comment>http://www.blogjava.net/cyantide/comments/297509.html</wfw:comment><comments>http://www.blogjava.net/cyantide/archive/2009/10/09/297509.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cyantide/comments/commentRss/297509.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyantide/services/trackbacks/297509.html</trackback:ping><description><![CDATA[前几天看到GOING MM关于<a class="postTitle2" href="../../goingmm/archive/2005/11/28/21642.html" id="viewpost1_TitleUrl">Hibernate Transaction</a> 的描述,这里顺便转载一篇hiberntae中锁机制的文章:<br />
<br />
&nbsp;&nbsp;
悲观锁定&nbsp;假定任何时刻存取数据时，都可能有另一个客户也正在存取同一笔数据，因而对数据采取了数据库层次的锁定状态，在锁定的时间内其它的客户不能对资
料进行存取，对于单机或小系统而言，这并不成问题，然而如果是在网络上的系统，同时间会有许多联机，如果每一次读取数据都造成锁定，其后继的存取就必须等
待，这将造成效能上的问题，造成后继使用者的长时间等待。<span lang="EN-US"><br />
乐观锁定（optimistic locking）则乐观的认为资料的存取很少发生同时存取的问题，因而不作数据库层次上的锁定，为了维护正确的数据，乐观锁定使用应用程序上的逻辑实现版本控制的解决。<br />
例如若有两个客户端，A客户先读取了账户余额1000元，之后B客户也读取了账户余额1000元的数据，A客户提取了500元，对数据库作了变更，此时
数据库中的余额为500元，B客户也要提取300元，根据其所取得的资料，1000-300将为700余额，若此时再对数据库进行变更，最后的余额就会不
正确。<br />
在不实行悲观锁定策略的情况下，数据不一致的情况一但发生，有几个解决的方法，一种是先更新为主，一种是后更新的为主，比较复杂的就是检查发生变动的数据来实现，或是检查所有属性来实现乐观锁定。<br />
Hibernate中透过版本号检查来实现后更新为主，这也是Hibernate所推荐的方式，在数据库中加入一个VERSON栏记录，在读取数据时连
同版本号一同读取，并在更新数据时递增版本号，然后比对版本号与数据库中的版本号，如果大于数据库中的版本号则予以更新，否则就回报错误。<br />
以刚
才的例子，A客户读取账户余额1000元，并连带读取版本号为5的话，B客户此时也读取账号余额1000元，版本号也为5，A客户在领款后账户余额
为500，此时将版本号加1，版本号目前为6，而数据库中版本号为5，所以予以更新，更新数据库后，数据库此时余额为500，版本号为6，B客户领款后要
变更数据库，其版本号为5，但是数据库的版本号为6，此时不予更新，B客户数据重新读取数据库中新的数据并重新进行业务流程才变更数据库。<br />
以Hibernate实现版本号控制锁定的话，我们的对象中增加一个version属性，例如：</span><span style="font-family: 宋体; font-size: 12pt;"> <span lang="EN-US"><o:p></o:p></span></span>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">public class Account {<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>private&nbsp;int version;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>....<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>public void setVersion(int version) {<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>this.version = version;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>public&nbsp;int getVersion() {<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return version;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>....<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">}<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><br />
而在映像文件中，我们使用optimistic-lock属性设定version控制，&lt;id&gt;属性栏之后增加一个&lt;version&gt;标签，例如： <o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">&lt;hibernate-mapping&gt;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>&lt;class name="onlyfun.caterpillar.Account" talble="ACCOUNT"<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>optimistic-lock="version"&gt;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;id...../&gt;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;version name="version" column="VERSION"/&gt;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>....<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>&lt;/class&gt;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">&lt;/hibernate-mapping&gt;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><br />
</span><span style="font-family: 宋体; font-size: 12pt;">　设定好版本控制之后，在上例中如果<span lang="EN-US">B
客户试图更新数据，将会引发StableObjectStateException例外，我们可以捕捉这个例外，在处理中重新读取数据库中的数据，同时将
B客户目前的数据与数据库中的数据秀出来，让B客户有机会比对不一致的数据，以决定要变更的部份，或者您可以设计程
式自动读取新的资料，并重复扣款业务流程，直到数据可以更新为止，这一切可以在背景执行，而不用让您的客户知道。<br />
</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-family: 宋体; font-size: 12pt;"><span lang="EN-US"><br />
&nbsp; 悲观锁定</span></span><span style="font-family: 宋体; font-size: 12pt;">在多个客户端可能读取同一笔数据或同时更新一笔数据的情况下，必须要有访问控制的手段，防止同一个数据被修改而造成混乱，最简单的手段就是对数据进行锁定，在自己进行数据读取或更新等动作时，锁定其它客户端不能对同一笔数据进行任何的动作。<span lang="EN-US"><br />
悲观锁定（Pessimistic Locking）一如其名称所示，悲观的认定每次资料存取时，其它的客户端也会存取同一笔数据，因此对该笔数据进行锁定，直到自己操作完成后解除锁定。</span></span><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><br />
</span><span style="font-family: 宋体; font-size: 12pt;">　悲观锁定通常透过系统或数据库本身的功能来实现，依赖系统或数据库本身提供的锁定机制，<span lang="EN-US">Hibernate即是如此，我们可以利用Query或Criteria的setLockMode()方法来设定要锁定的表或列（row）及其锁定模式，锁定模式有以下的几个：</span></span><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US"><o:p></o:p></span></p>
<ul type="disc">
    <li class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">LockMode.WRITE：在insert或update时进行锁定，Hibernate会在save()方法时自动获得锁定。<o:p></o:p></span>
    </li>
    <li class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">LockMode.UPGRADE：利用SELECT &#8230; FOR UPDATE进行锁定。<o:p></o:p></span>
    </li>
    <li class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">LockMode.UPGRADE_NOWAIT：利用SELECT &#8230; FOR UPDATE NOWAIT进行锁定，在Oracle环境下使用。<o:p></o:p></span>
    </li>
    <li class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">LockMode.READ：在读取记录时Hibernate会自动获得锁定。<o:p></o:p></span>
    </li>
    <li class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;"><span style="font-family: 宋体; font-size: 12pt;" lang="EN-US">LockMode.NONE：没有锁定。<o:p></o:p></span></li>
</ul>
<span style="font-family: 宋体; font-size: 12pt;">　也可以在使用<span lang="EN-US">Session的load()或是lock()时指定锁定模式以进行锁定。<br />
如果数据库不支持所指定的锁定模式，Hibernate会选择一个合适的锁定替换，而不是丢出一个例外（Hibernate参考手册10.6）。</span></span>
<img src ="http://www.blogjava.net/cyantide/aggbug/297509.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyantide/" target="_blank">微笑沙漠</a> 2009-10-09 10:29 <a href="http://www.blogjava.net/cyantide/archive/2009/10/09/297509.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>