【发布时间】:2017-11-26 01:30:47
【问题描述】:
我有一个 DAO 类中的一个方法,它在 2 个不同的 Oracle 表中插入记录。我希望记录要么插入表中,要么不插入。
为了实现这一点,我同时使用了 @Transactional 和 cn.setAutoCommit(false) 代码 sn-p。
为了测试,我故意把SQL的列名放错了,导致第二张表的数据插入失败。我的期望是,由于查询不正确,第二个表中的插入失败,因此数据不会插入到第一个表中。但由于某种原因,这并没有发生。记录仍然插入到第一个表中,第二个表没有插入记录。
看起来这里的实现不正确。不确定我在这里缺少什么。
EventLogDao.java
@Transactional
public long saveEventData(EventLog eventLog, String userId) throws SQLException {
Connection cn = this.dataSource.getConnection();
cn.setAutoCommit(false);
//(FIRST TABLE INSERTION - Table Name: EVENT_LOG)
//save data in event log table
long eventId = getNextEventIdSequence();
saveEventLogData(eventId, eventLog);
//(SECOND TABLE INSERTION - Table Name: EVENT_LOG_MESSAGE)
//save data in event log message table
saveEventLogMessageData(eventId, eventLog.getEventLogMessage());
cn.commit();
return eventId;
}
private void saveEventLogData(long eventId, EventLog eventLog) {
Object[] parameters = {eventId, eventLog.getRouteId(), eventLog.getEventType().getEventTypeId(),
eventLog.getOrderId(), eventLog.getIncomingEventTimestamp(), eventLog.getOutgoingEventTimestamp()};
int[] types = {Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP, Types.TIMESTAMP};
int rowsAffected = jdbcTemplate.update(INSERT_EVENT_LOG_SQL2, parameters, types);
System.out.println("rowsAffected (eventlog) = " + rowsAffected);
}
private int saveEventLogMessageData(long eventId, EventLogMessage eventLogMessage) {
Object[] parameters = {eventId, eventLogMessage.getIncomingEventMessage(), eventLogMessage.getOutgoingEventMessage()};
int[] types = {Types.INTEGER, Types.VARCHAR, Types.VARCHAR};
int rowsAffected = jdbcTemplate.update(INSERT_EVENT_LOG_MESSAGE_SQL2, parameters, types);
System.out.println("rowsAffected (eventLogMessage) = " + rowsAffected);
return rowsAffected;
}
applicationContext.xml
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<constructor-arg>
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
</constructor-arg>
<property name="propagationBehavior">
<util:constant static-field="org.springframework.transaction.support.DefaultTransactionDefinition.PROPAGATION_REQUIRED"/>
</property>
<property name="isolationLevel">
<util:constant static-field="org.springframework.transaction.support.DefaultTransactionDefinition.ISOLATION_READ_COMMITTED"/>
</property>
</bean>
<bean id="eventLogDao" class="com.ebayenterprise.publicapi.events.dao.EventLogDao">
<constructor-arg ref="dataSource" />
</bean>
请指导。
【问题讨论】:
-
我不确定,但我认为您使用的连接与事务处理的连接不同,当您从数据源检索连接时,此连接与事务无关,除非您是使用 JTA 事务和一些包装器。您必须区分容器和数据库事务,您能否发布有关您的配置的更多信息?
-
@karelss - 不确定这是否有帮助,但只是使用 applicationContext 配置更新了原始帖子
标签: java spring oracle spring-jdbc spring-transactions