2

Spring (バージョン 3.0) の「@Transactional」アノテーションを使用して、Spring でのトランザクション サポートを示していますが、これを機能させることはできません (このフォーラムや他のテクニカル フォーラムで人々が遭遇した同様の問題を見たにもかかわらず)。

ここに私のSpring構成エントリがありspring-application-context.xmlます:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>

  <tx:annotation-driven /> 

  <bean id="formatDao" class="com.gj.dao.FormatDao">
    <property name="dataSource" ref="dataSource"/>
  </bean>

テストクラスのトランザクションメソッドは次のとおりです。

  @Transactional(readOnly = true)
  public class FormatDaoTest
  {

      private static ApplicationContext context = new FileSystemXmlApplicationContext(
        "c:\\catalogue\\src\\com\\gj\\conf\\spring-application-context.xml");

      public static void main(String[] args)
      {
    FormatDaoTest test = new FormatDaoTest();
    test.doTransaction();
      }


      @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
      public void doTransaction()
      {

    IDao dao = (IDao) context.getBean("formatDao");

    Format newFormat = new Format(1, "Test Format 1");

    // Creating a single format
    dao.create(newFormat);

    List newFormatList = new ArrayList();
    newFormatList.add(new Format(2, "Test Format 2"));
    newFormatList.add(new Format(3, "Test Format 3"));
    newFormatList.add(new Format(4, "Test Format 4"));
    newFormatList.add(new Format(5, "Test Format 5"));

    // Creating a list of formats 
    dao.create(newFormatList);

    List updatedFormatList = new ArrayList();
    updatedFormatList.add(new Format(1, "My Test Format 1"));
    updatedFormatList.add(new Format(2, "My Test Format 2"));
    updatedFormatList.add(new Format(3, "My Test Format 3"));

    // Update a list of formats
    dao.update(updatedFormatList);

    Format updatedFormat = new Format(4, "My Test Format 4 with a long format description so allowed table column size is exceeded");

    // Update a single format resulting in a java.sql.SQLException: ORA-12899: value too large for column
    // "RSSPPF1_OWNER"."FORMAT"."FORMAT_DESC" (actual: 88, maximum: 30)
    dao.update(updatedFormat);


      }

  }

次の SQL 例外がスローされます (予想どおり)。

Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [UPDATE FORMAT SET format_desc = ? WHERE format_id = ?]; SQL state [72000]; error code [12899]; ORA-12899: value too large for column "RSSPPF1_OWNER"."FORMAT"."FORMAT_DESC" (actual: 88, maximum: 30)
  ; nested exception is java.sql.SQLException: ORA-12899: value too large for column "RSSPPF1_OWNER"."FORMAT"."FORMAT_DESC" (actual: 88, maximum: 30)

    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:602)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:811)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:833)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:260)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:264)
    at com.gj.dao.FormatDao.update(FormatDao.java:68)
    at com.gj.test.FormatDaoTest.doTransaction(FormatDaoTest.java:62)
    at com.gj.test.FormatDaoTest.main(FormatDaoTest.java:26)
  Caused by: java.sql.SQLException: ORA-12899: value too large for column "RSSPPF1_OWNER"."FORMAT"."FORMAT_DESC" (actual: 88, maximum: 30)

    at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
    at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:131)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:204)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:413)
    at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:1034)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:194)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:953)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1222)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3387)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3468)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1062)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:817)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:1)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:586)
    ... 7 more

ただし、例外がスローされた後、トランザクションはロールバックされず、例外がスローされる前の以前のデータベースの挿入と更新がFORMATテーブルにコミットされていることがわかります。

  FORMAT_ID FORMAT_DESC
  1     My Test Format 1
  2     My Test Format 2
  3     My Test Format 3
  4     Test Format 4
  5     Test Format 5

この例外に続いて、データベースに何もコミットされないことを期待していました。

誰かが私が間違っている場所を知っていますか?ここでいくつかの重要な概念が欠けていますか?

どんな助けでも大歓迎です!

4

1 に答える 1

6

@TransactionalSpringで管理されるBeanにのみ適用されます(高度な機能を構成していない場合)FormatDaoTestが、Springでは管理されません。

簡単な修正として、次のことができると思います。

public static void main(String[] args) {
    FormatDaoTest test = context.getAutowireCapableBeanFactory()
        .createBean(FormatDaoTest.class);
    test.doTransaction();
}  

より洗練されたソリューションとして、Spring TestContextフレームワークを使用できます。これは、すぐにトランザクション対応のテストをサポートします。9.3.5.4トランザクション管理を参照してください。

于 2011-03-18T11:42:34.023 に答える