httpリクエスト全体に対して1つのトランザクションを持つようにSpringMVCでMyBatisをセットアップする方法はありますか? 通常、MyBatis には Hibernate のようなものがありますOpenSessionInViewFilter
か、それともそのような動作を満たすために独自のフィルターを作成する必要がありますか?
4 に答える
「セッション」と「トランザクション」という概念に混乱しています。OSIV はセッションを開きます。1 つのセッションで複数のトランザクションが共存する場合があります。通常@Transactional
、ビジネス要件に応じて、コントローラーが使用するサービスに属性を配置する必要があります。
さらに、すべてに対する 1 つの大きなトランザクションはアンチパターンです。理想的には、ユーザーのアクションに対して読み取り/書き込みトランザクションを作成し、別の読み取り専用トランザクションでユーザーへの応答を作成することです。挿入/更新のために取得されたデータベース ロックが以前に解放されるため、リソースが節約されます。
単一のトランザクションを特定のリクエストにバインドする必要がある場合はTransactionTemplate
、Filter
. Spring によって管理されていない限り、@Transactional
onを使用できないと思います(例: Spring Security の Filters.Filter
FilterChain
これがあなたができることですTransactionTemplate
public class TransactionalFilter implements Filter {
private TransactionTemplate transactionTemplate;
public void destroy() {
}
public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain) throws ServletException, IOException {
transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
try {
chain.doFilter(req, resp);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
return null;
}
});
}
public void init(FilterConfig config) throws ServletException {
transactionTemplate = new TransactionTemplate(WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext()).getBean(PlatformTransactionManager.class));
}
}
私のアドバイスは、次のヘルプドキュメントを読むことです: http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/transaction.html
spring-mvc フレームワークの各部分を完全に制御できるわけではないため、spring-mvc の基本クラスで aop ポイントカットを使用してトランザクション (リクエストごとに実行されるメソッド) を開始することをお勧めします。これを見つけることができます。セクション10.5.2のアプローチ。ポイントカットするクラスがSpringによって初期化されていることを確認してください。そうしないと機能しません。