我正在使用 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
在此异常之后,我本来希望看到没有任何东西提交给数据库。
有谁知道我哪里出错了,我在这里错过了一些关键概念吗?
任何帮助将不胜感激!