Я использую аннотацию @Transactional для Spring (версия 3.0), чтобы продемонстрировать поддержку транзакций в 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
Я ожидал бы, что после этого исключения ничего не будет зафиксировано в базе данных.
Кто-нибудь знает, где я иду не так, и мне не хватает какой-то ключевой концепции здесь?
Любая помощь будет принята с благодарностью!