@Matheus Santz, you are correct!! When using multiple datasources, it is always a best practice to annotate the @Transactional with the TransactionManager reference.
TransactDataSourceConfig.java
package com.spsllc.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
@EnableTransactionManagement
public class TransactDataSourceConfig {
@Bean
@ConfigurationProperties("spsllc.datasource.transactdb")
public DataSourceProperties transactDataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = "transactdbDS")
@ConfigurationProperties("spsllc.datasource.transactdb.configuration")
public DataSource transactDataSource() {
return transactDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
public JdbcTemplate transactdbJdbcTemplate(@Qualifier("transactdbDS") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean
public NamedParameterJdbcTemplate transactdbNamedParameterJdbcTemplate(@Qualifier("transactdbDS") DataSource dataSource) {
return new NamedParameterJdbcTemplate(dataSource);
}
@Bean(name = "transactTransactionManager")
public TransactionManager transactTransactionManager() {
return new DataSourceTransactionManager(transactDataSource());
}
}
SearchLogRepository.java
package com.spsllc.repository.transactdb;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.spsllc.domain.SearchLogEntry;
import lombok.extern.slf4j.Slf4j;
@Repository
@Slf4j
public class SearchLogRepository {
@Autowired
@Qualifier("transactdbJdbcTemplate")
JdbcTemplate jdbcTemplate;
@Autowired
@Qualifier("transactdbNamedParameterJdbcTemplate")
NamedParameterJdbcTemplate nmParamjdbcTemplate;
@Transactional(transactionManager = "transactTransactionManager")
public void insert(List<SearchLogEntry> entries) {
String sql = "INSERT INTO search_log(member_id, weekof_metadata, week_begin_date, " +
"week_end_date, activity_date,type, name, contact_person, contact_type) " +
"VALUES(:memberId, :weekofMetadata, :weekBeginDate, " +
":weekEndDate, :activityDate, :type, :name, :contactPerson, :contactType);";
GeneratedKeyHolder generatedKeyHolder = new GeneratedKeyHolder();
int index = 0;
for (SearchLogEntry e : entries) {
nmParamjdbcTemplate.update(sql, new BeanPropertySqlParameterSource(e), generatedKeyHolder,
new String[] { "search_log_id" });
Integer id = generatedKeyHolder.getKey().intValue();
e.setSearchLogId(id);
log.info(e.toString());
index++;
/** uncomment to test the rollback
if(index > 5)
throw new RuntimeException("Testing @Transactional commit/rollback behavior");
*/
}
}
}