2011-03-18 116 views
2

为了演示Spring中的事务支持 ,我使用了Spring(3.0版)'@Transactional'注释,但无法正常工作(尽管看到过类似人们在此遇到的问题以及其他技术论坛)。在使用Spring 3时,事务不会回滚@Transactional注释

这里是spring-application-context.xml我的Spring配置项:

<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 

我本来期望看到没有提交到数据库这个异常以下。

有没有人知道我要去哪里错了,我在这里错过了一些关键概念?

任何帮助将不胜感激!

回答

6

@Transactional仅适用于Spring管理的bean(除非您配置了高级功能),而在您的情况下,FormatDaoTest不受Spring管理。

我想你可以做以下的快速修复:

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

作为一个更优雅的解决方案,你可以使用Spring TestContext框架,它支持事务感知测试开箱,见9.3.5.4 Transaction management

+0

Grr,正是我会写的:-)(+1) – 2011-03-18 12:05:42

+0

非常感谢!必须是真正明显的东西。 – user665909 2011-03-18 12:07:33

+0

不得不下载'cglib_2.2.jar'并添加到我的类路径中以使其工作。我会认为SPRING FRAMEWORK 3.1 M1会包含所有的依赖类吗?似乎有一个主题,我需要下载其他依赖瓶来克服我打的错误! – user665909 2011-03-18 12:56:19

相关问题