Hibernate内の書き込み専用の操作はブロックされていますか?私が実行した場合、私は、意味:Hibernate内の書き込み操作のブロック
session.save(data);
@Transactionalとして注釈されている方法から、それはすぐにこの行の後に実行され、別のスレッドからのすべての
session.get(id);
を呼び出し、ということが保証され、適切なデータ(nullではない)を返しますか?
Hibernate内の書き込み専用の操作はブロックされていますか?私が実行した場合、私は、意味:Hibernate内の書き込み操作のブロック
session.save(data);
@Transactionalとして注釈されている方法から、それはすぐにこの行の後に実行され、別のスレッドからのすべての
session.get(id);
を呼び出し、ということが保証され、適切なデータ(nullではない)を返しますか?
結果は、トランザクション分離レベルによって異なります。 Springでは、次の分離レベルが可能です。
DEFAULT 基礎となるデータストアのデフォルトの分離レベルを使用します。
READ_COMMITTED ダーティリードが防止されていることを示す定数です。再現不可能な読み取りとファントム読み取りが発生する可能性があります。
READ_UNCOMMITTED ダーティー・リード、非リピート・リード、ファントム・リードが発生する可能性があることを示す定数です。
REPEATABLE_READ ダーティー読み取りと反復不可能な読み取りが防止されていることを示す定数です。ファントムの読み取りが行われる可能性があります。
SERIALIZABLE ダーティー読み取り、反復不可能な読み取り、およびファントム読み取りが防止されることを示す定数です。
save()(またはflush())をコールしても、トランザクションがコミットされることは保証されません。 get()が呼び出される前にトランザクション(save()が呼び出された場所)がコミットした場合、常に新しいスレッドで正しい結果が得られます。ただし、トランザクションがコミットされていない場合、正しい結果を取得するかどうかは、トランザクション分離レベルによって異なります。 「ダーティリード」を許可する分離レベルで正しい結果が得られます。
悲観的なロックを明示的に使用しない限り、書き込み操作はブロックではありません。トランザクションでは、(デフォルトの分離レベルREAD_COMMITTEDを仮定して)このトランザクション外の誰にもun-committedが見えないことが起こります。あなたがsave()
とget()
が異なるスレッドで実行されていて、異なるトランザクションで実行されていると述べたので、save()がコミットされたかどうかはget()の時点で決まります。
これはどうすれば確認できますか?手動でトランザクションをコミットする必要がありますか?あるいは、フラグを設定してメソッドをTRANSACTIONALとして宣言できますか? – preslavrachev
なぜこの動作が正確に必要ですか?これが確実に行われるようにするには、分離レベルがREAD_UNCOMMITTEDのget()トランザクションを呼び出すメソッドを作成します。あなたはいくらか汚い読みを得るかもしれません。 –