0

2 人の異なる Web ユーザーが同じエンティティで作業するとどうなるかという質問があります。たとえば、共有エンティティには 4 つのフィールドがあります。

class HibernateSharedEntity
{
int id;
int a;
int b;
int c;
int d;
}

これで、両方のユーザーが同時にトランザクションを開きます。そのうちの 1 人がこのエンティティを更新しており、2 番目のユーザーがこのエンティティを読み取っています。以下の手順は、それをよりよく説明します。

時間 1: Hibernate エンティティはデータベースに保存され、値は a=b=c=d=0 および id=1 です。
時間 2: User1 が新しいトランザクションを開きます。
時間 3: User1 が id=1 の HibernateSharedEntity を読み取ります。
時間 4: User1 がすべてのフィールドを変更しています (例: a=2 、 b=3 、 c=4、d=5)。
時間 5: User1 がトランザクションをコミットしています。
時間 6: Hibernate が a=2 を更新中
時間 7: Hibernate が b=3 を更新
中 時間 8: ここで User2 が新しいトランザクションを開き、この共有エンティティを読み取ります。質問: 彼は何を取り出しましたか? a=2 、 b=3 、 c=0 、 d=0 のような半分更新されたエンティティをフェッチしたか?
時間 9: Hibernate が c=4 を更新
中 時間 10: Hibernate が d=5 を更新中

中途半端なインスタンスは避けたい。これは私のアプリの重要なポイントです。2 番目のユーザーがこの共有エンティティを取得したい場合、2 番目のユーザーはこの共有エンティティを a=b=c=d=0 状態 (コミット前) または a=2,b= の 2 つの状態でのみ読み取ることができます。 3,c=4,d=5状態(コミット後)。hibernate はこれらすべての値を更新するために 1 つの挿入を行うことができることを知っていますが、この共有エンティティは他の共有エンティティと関係があり、User1 によって更新される可能性があるため、私のアプリケーションではより複雑に見えます。したがって、今後、休止状態は、これら 2 つの共有エンティティを更新するために 1 つの挿入を行うことはできません。したがって、User1 が 1 つのトランザクションでより多くの共有エンティティを更新する場合、User2 がこれらのエンティティを「非同期状態」で読み取ることができる可能性はありますか?つまり、1 つのエンティティが更新されたが、別のエンティティがまだ更新されていない場合ですか?

複雑になる可能性があると思うので、もっと詳しく説明しようと思います。私のアプリケーションでは、共有エンティティを同期する必要があります。
たとえば、entity1 = {a=1,b=2,c=3,d=4}
entity2 = {a=5,b=6,c=7,d=8}のような 2 つの共有エンティティがあります。

そして今、User1 はこれらのエンティティを更新したいと考えています。たとえば、次の状態にし
ます
。 }

. User1 が更新トランザクションを行っている間、User2 はこれらの共有インスタンスを取得したいと考えており、User2 がこれらのエンティティを次のような状態で読み取っていることを避けたいと考えています:
entity1 = {a=0,b=0,c=0,d=0}
entity2 = {a=5,b=6,c=7,d=8}
ご覧のとおり、entity1 は更新されていますが、entity2 は更新されていません。これは私のアプリケーションの重要なポイントであり、そのような状況はあり得ません。どうすればこれを回避できますか? 休止状態はこれを処理していますか? 前もって感謝します。

4

2 に答える 2

1

最初のシナリオは不可能です。Hibernate は、トランザクションがコミットされた後ではなく、コミットされる前に変更をデータベースに書き込みます。ユーザー 2 は、最初のトランザクションがコミットされた後にエンティティを読み取るため、データベースにコミットされたものを読み取ります。ユーザー 2 が最初のトランザクションのコミット前にデータベースから読み取ると、最初のトランザクションの開始前の状態が読み取られます (データベース分離レベルがデフォルトの READ_COMMITTED である限り)。

Hibernate アプリケーションは、他のデータベース アプリケーションと変わりません。トランザクションの ACIDity は、Hibernate ではなく、データベースによって処理されます。エンティティは、ところで、共有されていません。すべての Hibernate セッションには、特定のエンティティの独自のコピーがあり、トランザクションでデータベースから読み取られたデータが含まれています。

データベース トランザクションと ACID とは何かについてお読みください。Hibernate を使用するかどうかは、何も変わりません。

于 2013-03-03T17:49:59.690 に答える
0

トランザクションは、DB (および休止状態) でのアトミック操作です。データベースエンジンは、ユーザーが半分更新されたエンティティを取得しないことを保証します (トランザクション管理権限を構成する場合;))。

アプリがデータの整合性に依存している場合は、何らかのエンティティのロックも実装する必要があります。ほとんどのユースケースでは楽観的ロックで十分です。(この用語がよくわからない場合は、グーグルで検索してみてください)。

于 2013-03-03T17:50:58.990 に答える