Привет, у меня есть устаревший код, который получает соединения jdbc через
DataSource.getConnection()
DataSource ограничен пространством имен Jndi.,
Предположим, что у меня есть функция, которая получает такие соединения:
foo(){
...
Connection con = DataSource.getConnection()
...
}
И я хочу запустить этот метод foo в четко определенной транзакции spring. Как бы я это сделал?
Я использовал TransactionAwareDataSourceProxy, и он работал довольно хорошо, прежде чем я перешел на что-то вроде JPA.
Сначала я мог синхронизировать транзакцию foo с моей транзакцией spring с этой конфигурацией.
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations"><list><value>classpath:/db.properties</value></list></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<constructor-arg ref="dbcpDataSource"/>
</bean>
<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:@${jdbc.url}:1521:${jdbc.db}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
<!-- <property name="defaultAutoCommit"><value>true</value></property> -->
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
После этого я перехожу на JPA, используя LocalContainerEntityManagerFactoryBean и JpaTransactionManager.
package setup;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
@EnableJpaRepositories
public class SpringContextConfiguration {
@Bean
public TestsSetup testSetup(){
return new TestsSetup();
}
@Bean
public TransactionAwareDataSourceProxy dataSource(){
TransactionAwareDataSourceProxy tp = new TransactionAwareDataSourceProxy();
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
ds.setUrl("jdbc:oracle:thin:@a.a.a.a:port:some");
ds.setUsername("user");
ds.setPassword("paswd");
ds.setDefaultAutoCommit(true);
tp.setTargetDataSource(ds);
return tp;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource);
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("setup");
return lef;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(true);
hibernateJpaVendorAdapter.setGenerateDdl(false);
hibernateJpaVendorAdapter.setDatabase(Database.ORACLE);
return hibernateJpaVendorAdapter;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
}
Теперь мои устаревшие блоки кода не синхронизируются с моими управляемыми транзакциями. Как я могу преодолеть эту проблему. Любые инструменты или комментарии приветствуются.
ИЗМЕНИТЬ