[Seasar-user:12554] Re: Seasar2トランザクションロールバックについて

今田 昇 [E-MAIL ADDRESS DELETED]
2008年 1月 18日 (金) 12:16:28 JST


こんにちは。
今田と申します。
 
******************************************************
dao を定義している dicon ファイルは下記の通りです。
test.dicon 
--------------------------------
<!-- Component auto regist. -->
  <component
      class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"jp.co.domain.dao.impl"</arg>
      <arg>".*DaoImpl"</arg>
    </initMethod>
  </component>
*******************************************************
 
と書いていらっしゃるということは、
 
*******************************************************
testServiceImpl.java 
--------------------------------
public class testServiceImpl extends PagerService implements testService { 
private testDao dao; 
public void setTestDao(testDao dao) { 
this.dao = dao; 
} 
public int updatePassWord(String strNo, String strPwd) { 
int iRtnValue = -1; 
iRtnValue = dao.updatePassWord("15", "tcl"); 
iRtnValue = dao.updatePassWord1("16", "abc"); 
return iRtnValue; 
} 
*******************************************************
 
で使用しているtestDaoインタフェース(?)の実装クラスtestDaoImplクラスを自分で
コーディングされているということですか?
 
もしそうであるなら、
testDaoImpl.javaのコードを見せてもらえないでしょうか?
その中で自分でトランザクションをコミットしたりしていないでしょうか?

-----Original Message-----
From: [E-MAIL ADDRESS DELETED] [mailto:[E-MAIL ADDRESS DELETED]]On Behalf Of Tidever Chenglong Tian
Sent: Friday, January 18, 2008 11:48 AM
To: seasar-user
Subject: [Seasar-user:12553]Seasar2トランザクションロールバックについて


tomcat6.0 
Seasar2.3.19 
SqlServer2005 
JDK1.6 
 
Seasar2 はtomcatサーバーでSqlServerを接続する時、一つのServiceで2件のUpdate文を実行すると、一番目は成功するが、2番目は失敗する。 
ログで、「トランザクションをロールバックしました」というメッセージを出したが、DBで一番目のUpdate文は更新した内容が依然として存在 
していて、正常にロールバックしない。これは何故か
 
グは下記の通り。 
2008/01/10 09:26:27.812 [DEBUG] トランザクションを開始しました 
2008/01/10 09:26:27.984 [DEBUG] UPDATE dbo.test 
SET USER_PWD = 'tcl' 
WHERE USER_NO = '15' 
2008/01/10 09:26:28.375 [DEBUG] 物理的なコネクションを取得しました 
2008/01/10 09:26:28.375 [DEBUG] 論理的なコネクションを取得しました 
2008/01/10 09:26:28.531 [DEBUG] 論理的なコネクションを閉じました 
2008/01/10 09:26:28.531 [DEBUG] 物理的なコネクションを閉じました 
2008/01/10 09:26:28.609 [DEBUG] UPDATE dbo.test1 
SET USER_PWD = 'abc' 
WHERE USER_NO = '16' 
2008/01/10 09:26:28.625 [DEBUG] 物理的なコネクションを取得しました 
2008/01/10 09:26:28.625 [DEBUG] 論理的なコネクションを取得しました 
2008/01/10 09:26:28.625 [DEBUG] 論理的なコネクションを閉じました 
2008/01/10 09:26:28.625 [DEBUG] 物理的なコネクションを閉じました 
2008/01/10 09:26:28.625 [DEBUG] トランザクションをロールバックしました 
2008/01/10 09:26:28.671 [ERROR] org.seasar.framework.exception.SQLRuntimeException: 
[ESSR0071]SQLで例外(ErrorCode=208, SQLState=42S02)が発生しました。理由は 
org.seasar.framework.exception.SSQLException: [ESSR0072]SQLで例外(SQL=[UPDATE dbo.test 
....
 
j2ee.dicon 
--------------------------------
<?xml version="1.0" encoding="Shift_JIS"?> 
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN" 
" http://www.seasar.org/dtd/components.dtd"> 
<components namespace="j2ee"> 
<!-- Seasar2トランザクションマネージャ --> 
<component name="transactionManager" 
class="org.seasar.extension.jta.TransactionManagerImpl"/> 
<!-- トランザクション属性 --> 
<component name="requiredTx" class="org.seasar.extension.tx.RequiredInterceptor"> 
<initMethod name="addRollbackRule"> 
<arg>@[E-MAIL ADDRESS DELETED]</arg> 
</initMethod> 
</component> 
<component name="basicResultSetFactory" 
class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/> 
<component name="basicStatementFactory" 
class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/> 
<!-- SQL Server 2005 --> 
<component name="sqlConnection" class="org.seasar.extension.dbcp.impl.XADataSourceImpl"> 
<property name="driverClassName">"com.microsoft.jdbc.sqlserver.SQLServerDriver"</property> 
<property name="URL">"jdbc:microsoft:sqlserver://192.168.1.216:1433;DatabaseName=test"</property> 
<property name="user">"sa"</property> 
<property name="password">"sa"</property> 
</component> 
<component name="sqlConnectionPool" class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl"> 
<property name="timeout">600</property> 
<property name="maxPoolSize">5</property> 
<property name="allowLocalTx">true</property> 
<property name="XADataSource">sqlConnection</property> 
<destroyMethod name="close"/> 
</component> 
<component name="dataSource" class="org.seasar.extension.dbcp.impl.DataSourceImpl"> 
<arg>sqlConnectionPool</arg> 
</component> 
</components> 
 
test.dicon 
--------------------------------
<components> 
<!--Aspect auto regist. --> 
<component class="jp.co.business.service.impl.testServiceImpl"> 
<aspect>j2ee.requiredTx</aspect> 
</component> 
</components> 
 


testServiceImpl.java 
--------------------------------
public class testServiceImpl extends PagerService implements testService { 
private testDao dao; 
public void setTestDao(testDao dao) { 
this.dao = dao; 
} 
public int updatePassWord(String strNo, String strPwd) { 
int iRtnValue = -1; 
iRtnValue = dao.updatePassWord("15", "tcl"); 
iRtnValue = dao.updatePassWord1("16", "abc"); 
return iRtnValue; 
} 
 
================================================================
小林さん
 
ご回答大変ありがとうございました。
dao を定義している dicon ファイルは下記の通りです。
test.dicon 
--------------------------------
<!-- Component auto regist. -->
  <component
      class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"jp.co.domain.dao.impl"</arg>
      <arg>".*DaoImpl"</arg>
    </initMethod>
  </component>
  <component
      class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"jp.co.business.service.impl"</arg>
      <arg>".*ServiceImpl"</arg>
    </initMethod>
  </component>
  <component
      class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <property name="instanceDef">
      @[E-MAIL ADDRESS DELETED]
    </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"jp.co.web.action"</arg>
      <arg>".*Action"</arg>
    </initMethod>
  </component>
 
testService を呼び出しているコード
--------------------------------
public class LoginAction extends BaseAction{
 private testService service;
 public void setTestService(testService service) {
  this.service = service;
 }
 public String doExecute(ActionMapping mapping,
   ActionForm form,
   HttpServletRequest request,
   HttpServletResponse response) {
  int iUpdateFlg = -1;
  iUpdateFlg = service.updatePassWord("15", "tcl");
  return SUCCESS;
 }
}
「トランザクションを開始しているコード」はソースで書いていません。
トランザクションの管理はS2基底より実行されるのでしょうか、ソースで明文に記述する必要がありますか。
尚、S2Containerが作成されたかをどのように判断しますか。
================================================================
ひがさん
 
ご回答大変ありがとうございました。
web.xmlに下記の配置があります。
web.xml
--------------------------------
<servlet>
 <servlet-name>s2servlet</servlet-name>
 <servlet-class>org.seasar.framework.container.servlet.S2ContainerServlet</servlet-class>
 <init-param>
  <param-name>configPath</param-name>
  <param-value>app.dicon</param-value>
 </init-param>
 <init-param>
  <param-name>debug</param-name>
  <param-value>false</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
 <servlet-name>s2servlet</servlet-name>
 <url-pattern>/s2servlet</url-pattern>
</servlet-mapping>
 
>S2Containerの生成は、S2ContainerServletに任せてください。
それでは、既にS2Containerの生成はS2ContainerServletに任せたことを説明するのでしょうか。
ほかに何かの配置が要りますか。


-------------- next part --------------
HTMLの添付ファイルを保管しました...
URL: http://ml.seasar.org/archives/seasar-user/attachments/20080118/2194dcea/attachment-0001.html 


Seasar-user メーリングリストの案内