よろしければ、Spring のトランザクションについていくつか質問があります。このDAOクラスがあるとしましょう:
public class MyDAO {
/**
* verifies if a certain record in DB contains 'True' in a certain Column named publishFlag
*/
@Transactional
public bloolean isBeingPublished(Long recordID){
...
}
/**
* sets the record's publishFlag column to true indicating that it's being published
*/
@Transactional
public boolean setBeingPublished(Long recordID){
...
}
}
そしてそれを使用する次のクラス:
public class MyClass {
@Autowired
MyDAO dao;
public void publishRecords(List<Long> ids){
for(Long id : ids){
if(!dao.isBeingPublished(id)){
dao.setBeingPublished(id);
//do something to publish the record
}
}
}
}
私の質問は次のとおりです。
まず、
!dao.isBeingPublished(id)
anddao.setBeingPublished(id)
は同じトランザクションで実行されますか、それとも別のトランザクションで実行されますか?2 番目の質問は同時実行性に関するものです。複数の
MyClass
インスタンスを作成でき、publishRecord
メソッドへの同時呼び出しが発生する可能性があるため、2 つの同時呼び出し!dao.isBeingPublished(id)
が両方とも同じ結果をもたらし、レコードが 2 回公開される可能性があります。 同期を作成することを検討しpublishRecords
ますが、アプリケーションが複数のサーバーに展開されると、同期宣言が役に立たなくなる可能性があります。データベースは、それらのサーバーに展開されたアプリ間の唯一の共有リソースであるため、トランザクションに関する質問です。
私の問題の正確な解決策は何ですか?春のトランザクションの伝播について読んだところREQUIRES_NEW
、現在実行中のトランザクションでも新しいトランザクションが作成されることがわかりましたが、それでも、それがどのように問題の解決策になるのかわかりません。
よろしくお願いいたします。