Forums: Open Discussion (Thread #18108)

Select For Update 使用時のTransaction例外について (2008-03-24 14:14 by Anonymous #35720)

Select For Update で行ロックをしている時に、別のスレッドで同じ「Select For Update」を実行した際に発生する「DataAccessException」を補足し、
BLogicResultにforwardの文字列”error”を渡して画面遷移させたいのですが、
「org.springframework.transaction.UnexpectedRollbackException」
が発生し、デフォルトのエラーページに遷移してしまいます。

ロック中の行にアクセスした際に出る例外発生時に、forwardで画面遷移させることはできないのでしょうか?

Reply to #35720×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: Select For Update 使用時のTransaction例外について (2008-03-24 14:26 by kimumasa #35721)

SQLの実行部分で
UnexpectedRollbackExceptionをcatchし、
”error”を渡して画面遷移させると
ご希望の動きになるかと思います。

ドライバにもよりますが行ロック以外の契機で
同例外が検知される事も予想されますので、
内容が正しく行ロックによるものかどうか?
を精査した上で、画面遷移させる事を
お勧めします。
Reply to #35720

Reply to #35721×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: Select For Update 使用時のTransaction例外について (2008-03-24 14:48 by Anonymous #35722)

早速のご回答ありがとうございます。

UnexpectedRollbackException
例外が発生している箇所がSQL実行時ではなく、RequestProcessorで発生しているようです。
そのため、UnexpectedRollbackExceptionはSQL実行時にキャッチできません。

-------------------------------------
[2008/03/24 14:37:31][WARN][RequestProcessor] 処理できない例外がスローされました: class org.springframework.transaction.UnexpectedRollbackException

※Strutsの Global-Exceptions タグで UnexpectedRollbackException を指定すると例外は発生しませんでした。
Reply to #35720

Reply to #35722×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: Select For Update 使用時のTransaction例外について (2008-03-24 16:02 by kimumasa #35725)

RequestProcessorから直接DAOをコールする且つ、
RequestProcessor自体をTransactionManagerで制御しているとは考えにくいです。

出来れば、スタックトレースを張ってもらえないでしょうか?
(固有の情報はマスキング願います)

RequestProcessor#processActionPerform()
からActionExサブクラスが実行され、
ここで、何かしらのRuntimeExceptionがスローされているものと思います。
※org.springframework.dao.DataAccessException系の何かかもしれません。


コメント頂いている情報から類推すると
ActionやBLogic等DIコンテナで管理されているクラスから例外が検知された後
RequestProcessor#processExceptionに処理が委譲され
log.warn(getInternal().getMessage("unhandledException", exception.getClass()));
により、ご指摘のメッセージ出力を行います。

この後、ExceptionHandlerが実行されますので
Global-Exceptions タグで UnexpectedRollbackExceptionを指定すると
例外ハンドラによって処理されています。
(例外は発生しているのですがハンドラによって処理されている)
Reply to #35722

Reply to #35725×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RERE: Select For Update 使用時のTransaction例外について (2008-03-24 16:18 by Anonymous #35726)

以下がスタックトレースになります。お忙しいところすみませんが、よろしくお願い致します。

[2008/03/24 16:09:04][DEBUG][BLogicAction] *** doExecuteBLogic() called. ***
[2008/03/24 16:09:04][DEBUG][BLogicAction] *** Starting blogic[$Proxy7]. ***
[2008/03/24 16:09:10][DEBUG][QueryDAOiBatisImpl] executeForObject Start.
[2008/03/24 16:09:10][INFO][XmlBeanDefinitionReader] Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
[2008/03/24 16:09:10][INFO][SQLErrorCodesFactory] SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
[2008/03/24 16:09:15][WARN][RequestProcessor] 処理できない例外がスローされました: class org.springframework.transaction.UnexpectedRollbackException
[2008/03/24 16:09:15][ERROR][RequestProcessorEx] sessionHash = 92B6A6718F87A87556EBC450D53005F391B6D2B8
[2008/03/24 16:09:15][ERROR][RequestProcessorEx] javax.servlet.ServletException: Transaction rolled back because it has been marked as rollback-only
at org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:535)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:433)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
at jp.terasoluna.fw.web.struts.action.RequestProcessorEx.process(RequestProcessorEx.java:149)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1085)
at org.apache.struts.action.RequestProcessor.processForwardConfig(RequestProcessor.java:398)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:241)
at jp.terasoluna.fw.web.struts.action.RequestProcessorEx.process(RequestProcessorEx.java:149)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at jp.co.nttdata.project.common.filter.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:177)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:595)
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:626)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:314)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy7.execute(Unknown Source)
at jp.terasoluna.fw.web.struts.actions.BLogicAction.doExecuteBLogic(BLogicAction.java:137)
at jp.terasoluna.fw.web.struts.actions.AbstractBLogicAction.doExecute(AbstractBLogicAction.java:263)
at jp.terasoluna.fw.web.struts.actions.ActionEx.execute(ActionEx.java:220)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
at jp.terasoluna.fw.web.struts.action.RequestProcessorEx.process(RequestProcessorEx.java:149)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1085)
at org.apache.struts.action.RequestProcessor.processForwardConfig(RequestProcessor.java:398)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:241)
at jp.terasoluna.fw.web.struts.action.RequestProcessorEx.process(RequestProcessorEx.java:149)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at jp.co.nttdata.project.common.filter.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:177)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:595)
Reply to #35720

Reply to #35726×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RERE: Select For Update 使用時のTransaction例外について (2008-03-24 17:29 by kimumasa #35728)

BLogic実装クラスで以下のイメージで実装している
のではと思っています。合っていますでしょうか?

BLogicResult execute(P params) {
try {
queryDAO.executeForObject("hoge", null);
} catch (RuntimeException e) {
// A
result.setResultString("error");
}
result.setResultString("success");
return result;
}

そして、Aの場所に
org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
を実装したらどうなるでしょうか?

お手数ですが、確認してもらえると助かります。
Reply to #35726

Reply to #35728×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

解決しました。 (2008-03-24 17:41 by Anonymous #35729)

>BLogic実装クラスで以下のイメージで実装している
のではと思っています。合っていますでしょうか?

その通りです。

ご指摘のように実装したところ、思い通りに画面遷移ができました。

お忙しいところ大変ありがとうございました。
Reply to #35720

Reply to #35729×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: 解決しました。 (2008-03-24 18:05 by kimumasa #35730)

補足で原因を書いておきます。

例のように実装する場合
1:DAO側では例外が投げられる
2:BLogic側では正常終了してSpringに通知
という流れになります。

しかし、
1の時点でrollbackしか出来ない状態になっているにも関わらず、
Springは2の情報を見てcommitをしに行くため、
本事象のような例外が出てきます。

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
を実装すると、2の結果がどうあれ
Springはフラグ判定の結果、rollbackしに行きますので
本事象の例外が起きなくなります。
Reply to #35729

Reply to #35730×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login