【发布时间】:2014-01-29 20:27:47
【问题描述】:
我在 spring 上处理两个事务,它引用了两个实体管理器,因此引用了两个数据源,而使用 @Transactional("transaction1") 它工作正常,但 @Transactional("transaction2") 抛出一个错误,指出没有找到活动事务。以下是一段代码:
@Bean(name = "transaction1")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactoryBean2()
.getObject());
return transactionManager;
}
@Bean(name = "transaction2")
public PlatformTransactionManager sermaTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager
.setEntityManagerFactory(entityManagerFactoryBean1()
.getObject());
return transactionManager;
}
各个实体经理:
@Bean(name = "entitymanager1")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean1() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource1());
entityManagerFactoryBean
.setPackagesToScan(new String[] { this.environment
.getProperty("db.packagesToScan") });
entityManagerFactoryBean
.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter());
Map<String, Object> jpaProperties = new HashMap<String, Object>();
jpaProperties.put("eclipselink.weaving", "false");
jpaProperties.put("eclipselink.logging.level", "INFO");
jpaProperties.put("eclipselink.logging.parameters", "true");
entityManagerFactoryBean.setJpaPropertyMap(jpaProperties);
return entityManagerFactoryBean;
}
@Bean(name = "entitymanager2")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean2() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource2());
entityManagerFactoryBean
.setPackagesToScan(new String[] { this.environment
.getProperty("db.packagesToScan") });
entityManagerFactoryBean
.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter());
Map<String, Object> jpaProperties = new HashMap<String, Object>();
jpaProperties.put("eclipselink.weaving", "false");
jpaProperties.put("eclipselink.logging.parameters", "true");
jpaProperties.put("eclipselink.logging.level", "INFO");
entityManagerFactoryBean.setJpaPropertyMap(jpaProperties);
return entityManagerFactoryBean;
}
各自的数据源:
@Bean("datasource1")
public DriverManagerDataSource dataSource1() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource .setDriverClassName(this.environment.getProperty("db.driver"));
dataSource.setUrl(this.environment.getProperty("db.url"));
dataSource.setUsername(this.environment
.getProperty("db.username.abc"));
dataSource.setPassword(this.environment
.getProperty("db.password.abc"));
return dataSource;
}
@Bean("datasource2")
public DriverManagerDataSource dataSource2() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource
.setDriverClassName(this.environment.getProperty("db.driver"));
dataSource.setUrl(this.environment.getProperty("db.url"));
dataSource.setUsername(this.environment.getProperty("db.username"));
dataSource.setPassword(this.environment.getProperty("db.password"));
return dataSource;
}
我的 genericDaoImpl 具有以下链接各个实体管理器:
@PersistenceContext(unitName = "entitymanager1")
private EntityManager em1;
@PersistenceContext(unitName = "entitymanager2")
private EntityManager em2;
当我执行 @Transactional("transaction1") 时,它工作正常,但是当我执行 @Transactional("transaction2") 时,它说没有活动事务。当我没有提到交易的限定符时,错误说找到了两个交易(transaction1,transaction2)。任何帮助都会很棒。
【问题讨论】:
-
我相信您需要在 applicationContext.xml 中声明建议以传播到事务
-
transactionManager1 正在传递 entityManagerFactoryBean2,是否正确?
-
您尝试过下面发布的配置吗?它正在工作
-
@jhadesdev 感谢您的回复,我按照您自动接线的方式进行操作,但我的两个交易似乎都附加了相同的数据源。当我在我的 daoimpl 上自动连接数据源时,两个不同的数据源有两个不同的用户/密码,但是当我为两个限定符执行 @Transactional("qualifierName") 时,它会获得相同的数据源。为什么会这样?我确保正确的数据源和实体管理器是自动装配的。
-
使用 JpaTransactionManager,您在给定时间只能在服务层中拥有一个活动事务。请参阅下面的方法 savePlanes 的示例。只有使用 entityManager1 所做的更改才会与使用 @Transaction("transactionManager1") 注释的方法内的数据库同步。使用 entityManager2 所做的更改将被忽略(尽管仍会执行读取)。我测试了这个配置并且它有效,如果你总是得到相同的事务,也许你在 web.xml 中使用 OpenEntityManagerInView 过滤器,或者 OpenSessionInView
标签: java spring jpa jdbc entity