DAO
クラスのいずれかで、2つの異なるOracleテーブルにレコードを挿入するメソッドがあります。レコードをテーブルの両方に挿入するか、挿入しないかのどちらかにします。@Transactionalとcn.setAutoCommit(false)を使用して複数のテーブルにレコードを挿入することはできません。jdbcTemplate
これを達成するために、私は@Transactional
とcn.setAutoCommit(false)
コードスニペットの両方を使用しています。
これをテストするために、私は意図的にSQL
に間違った列名を入れて、2番目のテーブルのデータ挿入が失敗するようにしました。私の予想は、誤ったクエリのために2番目のテーブルの挿入が失敗したため、最初のテーブルにデータが挿入されないということです。しかし何らかの理由でそれが起こらなかった。レコードはまだ最初のテーブルに挿入されており、2番目のテーブルにはレコードが挿入されていません。
実装がここで間違っていないようです。私がここで何が不足しているか分からない。
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>
案内してください。
私はよく分からないが、私はあなたが1とは別の接続を使用していると思いますトランザクションによって処理された場合、データソースから接続を取得するときに、JTAトランザクションおよびいくつかのラッパーを使用していない限り、この接続はトランザクションに関連付けられません。コンテナとデータベースのトランザクションを区別する必要があります。設定に関する詳細情報を投稿できますか? – karelss
@karelss - これが役立つかどうかはっきりしていませんが、applicationContext設定の元の投稿を更新したばかりです – user2325154