hibernate中的乐观锁和悲观锁

Jun 07, 2016 pm 02:50 PM
hibernate

hibernate支持两种锁:悲观锁(Pessimistic Locking)和乐观锁(Optimistic Locking) 悲观锁:指的是对数据库数据被外界的修改持保守态度(无论是本系统的事务处理,或者是外部系统的事务处理),在整个数据处理的过程数据都处于锁定的状态。hibernate中的

hibernate支持两种锁:悲观锁(Pessimistic Locking)和乐观锁(Optimistic Locking)

悲观锁:指的是对数据库数据被外界的修改持保守态度(无论是本系统的事务处理,或者是外部系统的事务处理),在整个数据处理的过程数据都处于锁定的状态。hibernate中的悲观锁,是依靠数据库中的锁机制(因为只有数据库层才能控制本系统和外部系统对数据库的数据操作)。

例如”select * from user where userName=’Johnson’ for update“这条sql锁定了user表中所有userName=’Johnson’的记录,本次事务提交之前,外界无法修改这些记录。

hibernate中的悲观锁,也是基于数据库的锁机制实现的。

<code class=" hljs lasso"><span class="hljs-built_in">String</span> hqlStr <span class="hljs-subst">=</span><span class="hljs-string">"from TUser as user where user.name='Lili'"</span>;
Query query <span class="hljs-subst">=</span> session<span class="hljs-built_in">.</span>createQuery(hqlStr);
query<span class="hljs-built_in">.</span>setLockMode(<span class="hljs-string">"user"</span>,LockMode<span class="hljs-built_in">.</span>UPGRADE); <span class="hljs-comment">//加锁</span>
<span class="hljs-built_in">List</span> userList <span class="hljs-subst">=</span> query<span class="hljs-built_in">.</span><span class="hljs-built_in">list</span>();<span class="hljs-comment">//执行查询,获取数据</span></code>
ログイン後にコピー

上面的代码中setLockMode第一个参数指定了别名为user的返回的记录进行上锁。
生成的sql为:

<code class=" hljs applescript">select tuser0_.<span class="hljs-property">id</span> <span class="hljs-keyword">as</span> <span class="hljs-property">id</span>, tuser0_.<span class="hljs-property">name</span> <span class="hljs-keyword">as</span> <span class="hljs-property">name</span>, tuser0_.group_id
<span class="hljs-keyword">as</span> group_id, tuser0_.user_type <span class="hljs-keyword">as</span> user_type, tuser0_.sex <span class="hljs-keyword">as</span> sex
<span class="hljs-keyword">from</span> t_user tuser0_ <span class="hljs-keyword">where</span> (tuser0_.<span class="hljs-property">name</span>='Erica' ) <span class="hljs-keyword">for</span> update</code>
ログイン後にコピー

可见hibernate通过数据库中的for update子句实现悲观锁机制。
hibernate的加锁模式:
LockMode.NONE : 无锁机制。
LockMode.WRITE : Hibernate 在 Insert 和 Update 记录的时候会自动获取。
LockMode.READ : Hibernate 在读取记录的时候会自动获取。
以上这三种锁机制一般由 Hibernate 内部使用,如 Hibernate 为了保证 Update过程中对象不会被外界修改,会在 save 方法实现中自动为目标对象加上 WRITE 锁。
LockMode.UPGRADE :利用数据库的 for update 子句加锁。
LockMode. UPGRADE_NOWAIT : Oracle 的特定实现,利用 Oracle 的 for update nowait 子句实现加锁。
上面这两种锁机制是我们在应用层较为常用的,加锁一般通过以下方法实现:
Criteria.setLockMode
Query.setLockMode
Session.lock

相对于悲观锁,乐观锁的锁机制就显得比较宽松。悲观锁大部分情况依靠数据库的锁机制实现,来保证最大程度的独占性。但另一方面数据库的开销非常大,尤其对于长事务来说。

乐观锁大部分是基于数据版本(version)记录机制实现。即在数据表中增加一个版本标识,读取出数据时,连带这个版本标识一起读出,更新数据的时候,把版本标识加1。将提交版本数据跟数据库中当前版本信息对比,如果提交的数据中版本号大于数据表当前的版本号,则允许更新,否则认为是过期数据。

hibernate的乐观锁主要有两种方式:version和时间戳

举个配置的例子:

<code class=" hljs xml">    <span class="hljs-pi"><?xml version="1.0"?></span>  
    <span class="hljs-doctype"><!DOCTYPE hibernate-mapping PUBLIC  
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"></span>  
    <span class="hljs-tag"><<span class="hljs-title">hibernate-mapping</span>></span>  
        <span class="hljs-tag"><<span class="hljs-title">class</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"test.Dir"</span> <span class="hljs-attribute">table</span>=<span class="hljs-value">"t_dir"</span>></span>  
            <span class="hljs-tag"><<span class="hljs-title">id</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"id"</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"string"</span> <span class="hljs-attribute">unsaved-value</span>=<span class="hljs-value">"null"</span>></span>  
             <span class="hljs-tag"><<span class="hljs-title">column</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"id_"</span> <span class="hljs-attribute">sql-type</span>=<span class="hljs-value">"char(32)"</span> <span class="hljs-attribute">not-null</span>=<span class="hljs-value">"true"</span> /></span>  
             <span class="hljs-tag"><<span class="hljs-title">generator</span> <span class="hljs-attribute">class</span>=<span class="hljs-value">"uuid.hex"</span> /></span>  
        <span class="hljs-tag"></<span class="hljs-title">id</span>></span>  
        <span class="hljs-comment"><!--这里version节点必须要配在id之后--></span>
            <span class="hljs-tag"><<span class="hljs-title">version</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"version_"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"version"</span> /></span>  
            <span class="hljs-tag"><<span class="hljs-title">property</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"name"</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"name_"</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"string"</span>/></span>  
            <span class="hljs-tag"><<span class="hljs-title">property</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"size"</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"size_"</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"long"</span> /></span>  
            <span class="hljs-tag"><<span class="hljs-title">many-to-one</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"dir"</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"pid_"</span> <span class="hljs-attribute">class</span>=<span class="hljs-value">"test.Dir"</span> /></span>  
        <span class="hljs-tag"></<span class="hljs-title">class</span>></span>  
    <span class="hljs-tag"></<span class="hljs-title">hibernate-mapping</span>></span>  </code>
ログイン後にコピー

乐观锁带来的负面问题:如果两个不同的事务同时读取一条数据并进行更新时,程序会报异常:org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)。这时候就要捕获异常,然后处理并提醒用户再次提交。
同样,乐观锁也有局限性。就是只控制了本系统的事务并发操作,而外部系统对数据表的操作却无法控制,此时有个解决办法就是:在存储过程里实现乐观锁机制,这样无论是本系统或是外部系统的事务操作,数据库都可以控制。所以,在设计阶段,尽量考虑到各种情况,究竟是在程序端实现好,还是数据库端实现比较好。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

SpringBoot プロジェクトに Hibernate を統合する方法 SpringBoot プロジェクトに Hibernate を統合する方法 May 18, 2023 am 09:49 AM

SpringBoot プロジェクトへの Hibernate の統合 はじめに Hibernate は、Java オブジェクトをデータベース テーブルにマップして永続化操作を容易にする、人気のある ORM (オブジェクト リレーショナル マッピング) フレームワークです。 SpringBoot プロジェクトでは、Hibernate を統合すると、データベース操作をより簡単に実行できるようになります。この記事では、SpringBoot プロジェクトに Hibernate を統合する方法と、対応する例を示します。 1.依存関係の導入pom.xml ファイルに次の依存関係を導入します: org.springframework.bootspring-boot-starter-data-jpam

Java エラー: Hibernate エラー、処理方法と回避方法 Java エラー: Hibernate エラー、処理方法と回避方法 Jun 25, 2023 am 09:09 AM

Java は、ソフトウェア開発の分野で広く使用されているオブジェクト指向プログラミング言語です。 Hibernate は、Java オブジェクトの永続性を管理するためのシンプルかつ効率的な方法を提供する、人気のある Java 永続性フレームワークです。ただし、開発プロセス中に Hibernate エラーが発生することが多く、これらのエラーによりプログラムが異常終了したり、不安定になったりする可能性があります。 Hibernate エラーを処理および回避する方法は、Java 開発者が習得しなければならないスキルとなっています。この記事では一般的な Hib を紹介します。

Hibernateとmybatisの違いは何ですか Hibernateとmybatisの違いは何ですか Jan 03, 2024 pm 03:35 PM

Hibernate と mybatis の違い: 1. 実装方法、2. パフォーマンス、3. オブジェクト管理の比較、4. キャッシュのメカニズム。詳細な紹介: 1. 実装方法、Hibernate はオブジェクトをデータベース テーブルにマップする完全なオブジェクト/リレーショナル マッピング ソリューションですが、MyBatis では開発者が SQL ステートメントと ResultMap を手動で記述する必要があります; 2. パフォーマンス、開発速度の点で Hibernate は可能です。 MyBatis は、Hibernate が DAO 層などを簡素化するためです。

Java Hibernate における 1 対多および多対多の関係のマッピング方法は何ですか? Java Hibernate における 1 対多および多対多の関係のマッピング方法は何ですか? May 27, 2023 pm 05:06 PM

Hibernate の 1 対多および多対多 Hibernate は、Java アプリケーションとリレーショナル データベース間のデータ アクセスを簡素化する優れた ORM フレームワークです。 Hibernate では、1 対多および多対多の関係を使用して、複雑なデータ モデルを処理できます。 Hibernate の 1 対多 Hibernate では、1 対多の関係は、1 つのエンティティ クラスが他の複数のエンティティ クラスに対応することを意味します。たとえば、1 つの注文は複数の注文アイテム (OrderItem) に対応することができ、1 人のユーザー (User) は複数の注文 (Order) に対応することができます。 Hibernate で 1 対多の関係を実装するには、エンティティ クラスでコレクション属性を定義して格納する必要があります。

Hibernate で一括挿入更新操作を実行するにはどうすればよいですか? Hibernate で一括挿入更新操作を実行するにはどうすればよいですか? Aug 27, 2023 pm 11:17 PM

この記事では、Hibernate で一括挿入/更新を実行する方法を説明します。 SQL ステートメントを実行するときは、データベースに対してネットワーク呼び出しを行うことによって実行されます。ここで、データベース テーブルに 10 個のエントリを挿入する必要がある場合、10 回のネットワーク呼び出しを行う必要があります。代わりに、バッチ処理を使用してネットワーク呼び出しを最適化できます。バッチ処理を使用すると、単一のネットワーク呼び出しで一連の SQL ステートメントを実行できます。これを理解して実装するには、エンティティを定義しましょう- @EntitypublicclassParent{@Id@GeneratedValue(strategy=GenerationType.AUTO)

Java 言語による Hibernate フレームワークの概要 Java 言語による Hibernate フレームワークの概要 Jun 10, 2023 am 11:35 AM

Hibernate は、リレーショナル データベースと Java プログラムの間のデータ マッピングを相互にバインドするオープン ソースの ORM フレームワークで、開発者がデータベース内のデータに簡単にアクセスできるようにします。 Hibernate フレームワークを使用すると、SQL ステートメントを作成する作業が大幅に軽減され、アプリケーションの開発効率と再利用性が向上します。以下の観点から Hibernate フレームワークを紹介していきます。 1. Hibernate フレームワークの利点: オブジェクト リレーショナル マッピング、データベース アクセスの詳細の隠蔽、開発の容易化

Hibernate の 2 次キャッシュはどのように機能しますか? Hibernate の 2 次キャッシュはどのように機能しますか? Sep 14, 2023 pm 07:45 PM

キャッシュは、クエリ実行時のデータベース ネットワーク呼び出しを減らすのに役立ちます。レベル 1 キャッシュとセッション リンク。これは暗黙的に実装されます。 1 次キャッシュは、セッション オブジェクトが存在するまで存在します。セッション オブジェクトが終了または閉じられると、キャッシュされたオブジェクトはなくなります。 2 次キャッシュは複数のセッション オブジェクトに対して機能します。セッションファクトリーとリンクされています。 2 次キャッシュ オブジェクトは、単一のセッション ファクトリを使用するすべてのセッションで使用できます。これらのキャッシュ オブジェクトは、特定のセッション ファクトリが閉じられると終了します。 2 次キャッシュを実装するには、2 次キャッシュを使用するための次の依存関係を追加する必要があります。 <!--https://mvnrepository.com/artifact/net.sf.ehcache/ehcache--><de

Java フレームワーク テクノロジ スタックの深い理解: Spring MVC、Hibernate、MyBatis などの一般的な Java フレームワークを調査します。 Java フレームワーク テクノロジ スタックの深い理解: Spring MVC、Hibernate、MyBatis などの一般的な Java フレームワークを調査します。 Dec 26, 2023 pm 12:50 PM

Java フレームワーク テクノロジ スタック: SpringMVC、Hibernate、MyBatis など、一般的に使用される Java フレームワークを紹介します。Java の継続的な開発に伴い、開発プロセスを簡素化するために、ますます多くのフレームワークが開発されています。その中でも、SpringMVC、Hibernate、MyBatis などは、Java 開発で最もよく使用されるフレームワークの 1 つです。この記事では、読者がこれらのフレームワークをよりよく理解し、適用できるように、これらのフレームワークの基本概念と使用法を紹介します。まずはSPを紹介します

See all articles