我在spring项目中使用了多个数据源。 我在项目启动时通过手动配置启用/禁用它们。 一次所有的人都可能处于活动状态 因此,transactionManager bean可能处于活动状态或不处于活动状态。
我在Spring配置类中通过@Conditional注释实现了它。 当我在方法上使用禁用事务注释时,会出现NoSuchBeanDefinitionException。
当我有条件地定义transactionManager bean时,如何在方法上使用事务注释?
archiveTransactionManager bean不是通过@Conditional注释创建的,我希望Spring跳过检查条件事务管理器的bean验证。
对于条件sessionFactory bean,我将Autowired注释中的“ required”参数设置为false,以防止spring抛出NoSuchBeanDefinitionException,但是我该如何对@Transactional进行操作?
配置类
@Bean("archiveTransactionManager")
@Conditional(ArchiveCondition.class)
public HibernateTransactionManager archiveTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(archiveSessionFactory());
return transactionManager;
}
交易方法
@Transactional(value = "archiveTransactionManager", readOnly = true)
private List<DocumentItem> loadArchivedDocumentItem() {...}
用法
if(GeneralSetting.isArchive)
documentService.loadArchivedDocumentItem();
当前结果:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'archiveTransactionManager' available: No matching PlatformTransactionManager bean found for qualifier 'archiveTransactionManager' - neither qualifier match nor bean name match!
在某些不是由条件创建的情况下,我希望有条件transactionManager bean的春季跳过bean验证。
答案 0 :(得分:2)
无论何时禁用archive_mode,我都会实现一个无操作SessionFactory并在spring配置类中实例化它:
SpringConfig.java
@Bean("archiveSessionFactory")
public SessionFactory archiveSessionFactory() {
return ServerConf.ARCHIVE_MODE ? createNormalSessionFactory() : new DummySessionFactory();
}
@Bean("archiveTransactionManager")
public HibernateTransactionManager archiveTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(archiveSessionFactory());
return transactionManager;
}
DummySessionFactory.java
public class DummySessionFactory implements SessionFactory {
...
// These two methods call in spring initializing and we have to implement them
@Override
public Metamodel getMetamodel() {
return new MetamodelImpl(null);
}
@Override
public Map<String, Object> getProperties() {
return null;
}
//Throw suitable exception in other methods
@Override
public Session getCurrentSession() throws HibernateException {
throw new HibernateException("Desired mode is Disabled");
}
...
}
答案 1 :(得分:0)
我会将其视为后备情况,在这种情况下您必须在失败后恢复。在这种情况下,请使用
注释方法调用方法 @Transactional(value = "archiveTransactionManager", readOnly = true)
在失败(或异常)的情况下,调用方法带有
@Transactional(value = "alternativeTransactionManager", readOnly = true)
public void doSomething() {
try {
tryFirst();
} catch (Exception e) {
tryAlternative();
}
}
@Transactional(value = "archiveTransactionManager", readOnly = true)
public void tryFirst() {
}
@Transactional(value = "alternativeTransactionManager", readOnly = true)
public void tryAlternative() {
}
请记住,您必须同时声明它们。
答案 2 :(得分:-1)
您使用了错误的注释来命名bean。在注入点上使用@Qualifier
来指定名称。您需要使用@Bean
为bean命名。因此,您的bean定义需要如下所示:
@Bean("archiveTransactionManager")
@Conditional(ArchiveCondition.class)
public HibernateTransactionManager archiveTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(archiveSessionFactory());
return transactionManager;
}