@Transactional
アノテーションの概要
Springなどでトランザクションを張って何か処理をしたい場合、@Transactional
アノテーションを使用すると思うのですが、readOnly
というオプションがあり、以下のように使います。
@Repository
open class HogeRepository {
@Transactional(readOnly = true)
open fun findAll(): HogeModel{
return HogeModel()
}
}
readOnlyなのにコミットできる場合がある
この@Transactional(readOnly = true)
内で更新処理を行って例外がthrowされると基本的にはロールバックしてくれます。
ただ、IOException
のような検査例外はスルーされたりするようです。このため、サードパーティーのライブラリなどを使用している場合には上記のロールバックが行われない場合もあります。この場合はrollbackFor
をうまく指定してあげる必要があります。
トランザクションが貼られる
@Transactional
アノテーションの名前の通り、トランザクションを貼ります。なので、要件で不必要なときは非機能的な観点でつけないほうがよいです。
以下4つの場合で、MySQLでSHOW FULL PROCESSLIST\G
を用いて確認したところ、すべてでトランザクションが貼られていました。トランザクション分離レベルで制御できているなら、基本は使用しないほうがよさそうです。
@Transactional
open fun test() {
sleep(10000L)
hogeRepository.findAll()
}
@Transactional
open fun test() {
hogeRepository.findAll()
sleep(10000L)
}
@Transactional(readOnly = true)
open fun test() {
sleep(10000L)
hogeRepository.findAll()
}
@Transactional(readOnly = true)
open fun test() {
hogeRepository.findAll()
sleep(10000L)
}