No transaction aspect-managed TransactionStatus in scopeエラー

今回は、トランザクションエラーの「No transaction aspect-managed TransactionStatus in scope」が発生したときに解決方法についてメモしていきたいと思います。

エラーと解決

@Transactionalアノテーションをメソッドに付与するときはpublicメソッドである必要があります。

public class SomeService() {
	@Transactional
	private void some() {
		...
	}	
}

you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.

private, protected, defalutアクセス制御がついているメソッドには正常に動作しません。なお、コンパイルも透し、実行時にエラーにもならないらしいので、注意が必要です。

上記のサンプルコードではsomeメソッドのアクセス制御をprivateからpublicに変更する必要があります。

@Transactionalアノテーションが付与されていないメソッドから@Transactionalが付与されているメソッドを呼び出す時

public class SomeService() {
	
	public void some1() {
		test2();
	}

	@Transactional
	public void some2() {
		...
	}	
}

この場合にも該当エラーメッセージが表示されます。詳細な説明は以下で説明します。

@Transactional(宣言的トランザクション)はProxy基盤で、AOPを使って実現されていてこれはMethodまたはClass(トランザクション対象のメソッドやクラス)が実行される前後の段階(トランザクション境界)で自動でトランザクションを実行されます。

@Transactionalはインスタンス内で最初に呼び出されたメソッドやクラスの属性を継ぎます。

つまり、同じクラス(Bean)内で最初に呼ばれるメソッドに@Transactionalアノテーションが付与されていないとそのメソッド(some1メソッド)からアノテーションが付与されているメソッド(some2メソッド)を呼び出しても動作しないです。

解決方法としては2つまります。

  • サンプルコードでは呼び出し元のメソッド(some1メソッド)に@Transactionalアノテーションを付与し、some2メソッドのアノテーションを削除する。
  • 別途クラス(Bean)を作成して、some2メソッドを実装して使う。

「別途クラス(Bean)を作成して、some2メソッドを実装して使う。」は念のため、サンプルコードも記載しておきます。

public class Some1Service() {
	@Autowired
	private Some2Service some2Service;

	public void some1() {
		some2Service.some2();
	}
}


public class Some2Service() {
	@Transactional
	public void some2() {
		...
	}
}

参考

https://www.programmerall.com/article/24721242523/

https://blog.naver.com/PostView.naver?blogId=varkiry05&logNo=221617256419

コメントを残す