現在、Spring Hibernate (サービスおよび daoImpl クラスのアノテーションによるトランザクション) で競合の問題が発生しています。これが私が遭遇したものです:
テーブル:
- デバイスの種類: ID (シリアル)、名前
- デバイス: id (シリアル)、device_identifier、device_type_id、ip_address
device_identifier と device_type_id は共に一意であることに注意してください
マルチスレッドプロセスで私が持っているもののスニペットは次のとおりです。
if(deviceDao.findByIdentifierAndTypeId(identifier, typeId) == null){
Device newDevice = new Device();
newDevice.setIdentifier(identifier);
newDevice.setTypeId(typeId);
deviceDao.add(newDevice);
}
何が起こるかというと、websocket 経由でデバイスをリッスンするサーバーがあり (ここではおそらく重要な詳細ではない)、サーバーは最初にデバイスがデータベースに既に存在するかどうかを判断しようとし、まだ見つかっていない場合はデバイスレコードが作成されます。
今私が抱えている問題は、サーバーがデバイスからの複数のメッセージを処理できる (デバイスからのメッセージごとにスレッドが作成される) ため、競合状態になることです。
だからこれを想像してください:
デバイス A は 2 つのメッセージを次々に送信します。
Sends hello message Sends "here is my ip" message
| |
| |
| |
does not see device in DB |
tries to insert does not see device in DB
| tries to insert
Insert completed |
Failed to insert (Unique key constraints not met)
明らかに、デバイスが 2 回目に挿入されるときに、一意の制約によってエラーが発生します。しかし、最初の挿入が完了すると、Spring はそれを拾い上げて、2 番目のスレッドが再度挿入しようとするときに、挿入する必要がないことを知ることができると考えていました。しかし、さまざまな伝播モードと分離モードを試したにもかかわらず、これは起こりませんでした。非常に基本的なものが欠けているに違いありません。これを修正する方法について正しい方向を教えてください。返信ありがとうございます。必要/要求があれば、より多くの情報を提供します。