📄 transactions.html
字号:
}s.disconnect();</pre><p> 接下来: </p><pre class="programlisting">s.reconnect();try { tx = s.beginTransaction(); bar.setFooTable( new HashMap() ); Iterator iter = fooList.iterator(); while ( iter.hasNext() ) { Foo foo = (Foo) iter.next(); s.lock(foo, LockMode.READ); //check that foo isn't stale bar.getFooTable().put( foo.getName(), foo ); } tx.commit();}catch (Exception e) { if (tx!=null) tx.rollback(); throw e;}finally { s.close();}</pre><p> 从上面的例子可以看到<tt class="literal">Transaction</tt>和<tt class="literal">Session</tt>之间是多对一的关系。一个<tt class="literal">Session</tt>表示了应用程序与数据库之间的一个对话,<tt class="literal">Transaction</tt>把这个对话分隔成一个个在数据库级别具有原子性的单元。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="transactions-locking"></a>10.6. 悲观锁定(Pessimistic Locking)</h2></div></div><div></div></div><p> 用户不需要在锁定策略上花费过多时间,通常我们可以对JDBC连接选定一种隔离级别(isolationn level),然后让数据库完成所有的工作。高级用户可能希望得到悲观锁定或者在新的事务开始时重新得到锁。 </p><p> Hibernate一直都会使用数据库的锁定机制,而不会在内存中锁定对象。 </p><p> <tt class="literal">LockMode</tt>类定义了Hibernate需要的不同的锁级别。锁由以下的机制得到: </p><div class="itemizedlist"><ul type="disc" compact><li><p> <tt class="literal">LockMode.WRITE</tt>在Hibernate更新或插入一行数据时自动得到。 </p></li><li><p> <tt class="literal">LockMode.UPGRADE</tt>在用户通过<tt class="literal">SELECT ... FOR UPDATE</tt>这样的特定请求得到,需要数据库支持这种语法。 </p></li><li><p> <tt class="literal">LockMode.UPGRADE_NOWAIT</tt>在用户通过<tt class="literal">SELECT ... FOR UPDATE NOWAIT</tt>这样的特定请求在Oracle数据库环境下得到。 </p></li><li><p> <tt class="literal">LockMode.READ</tt>在Hibernate在不断读(Repeatable Read)和序列化(Serializable)的隔离级别下读取数据时得到。也可以通过用户的明确请求重新获得。 </p></li><li><p> <tt class="literal">LockMode.NONE</tt>表示没有锁。所有对象在<tt class="literal">Transaction</tt>结束时会切换到这种锁模式,通过调用<tt class="literal">update()</tt>或者<tt class="literal">saveOrUpdate()</tt>与会话进行关联的对象,开始时也会在这种锁模式。 </p></li></ul></div><p> “明确的用户请求”会以下的几种方式出现: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 调用<tt class="literal">Session.load()</tt>,指定一种<tt class="literal">LockMode</tt>。 </p></li><li><p> 调用<tt class="literal">Session.lock()</tt>。 </p></li><li><p> 调用<tt class="literal">Query.setLockMode()</tt>。 </p></li></ul></div><p> 如果在调用<tt class="literal">Session.load()</tt>时指定了<tt class="literal">UPGRADE</tt>或者<tt class="literal">UPGRADE_NOWAIT</tt>,并且请求的对象还没有被会话调入,那么这个对象会以<tt class="literal">SELECT ... FOR UPDATE</tt>的方式调入。如果调用<tt class="literal">load()</tt>在一个已经调入的对象,并且这个对象调入时的锁级别没有请求时来得严格,Hibernate会对这个对象调用<tt class="literal">lock()</tt>。 </p><p> <tt class="literal">Session.lock()</tt>会执行版本号检查的特定的锁模式是:<tt class="literal">READ</tt>,<tt class="literal">UPGRADE</tt>或者<tt class="literal">UPGRADE_NOWAIT</tt>。(在<tt class="literal">UPGRADE</tt>或者<tt class="literal">UPGRADE_NOWAIT</tt>,<tt class="literal">SELECT ... FOR UPGRADE</tt>使用的情况下。) </p><p> 如果数据库不支持所请求的锁模式,Hibernate将会选择一种合适的受支持的锁模式替换(而不是抛出一个异常)。这确保了应用具有可移植性。 </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manipulatingdata.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="queryhql.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">第 9 章 操作持久化数据(Manipulating Persistent Data) </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 第 11 章 Hibernate查询语言(Query Language), 即HQL</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -