5

我在基于注释的配置类中配置了两个事务管理器:

@Configuration
@EnableTransactionManagement
public class DBConfig implements TransactionManagementConfigurer {

//...

@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
    return defTransactionManager();
}

@Bean
@Qualifier("defSessionFactory")
public LocalSessionFactoryBean defSessionFactory() {
    LocalSessionFactoryBean sfb = new LocalSessionFactoryBean();
    sfb.setDataSource(defDataSource());

    Properties props = new Properties();
    //...

    sfb.setHibernateProperties(props);
    sfb.setPackagesToScan("my.package");

    return sfb;
}

@Bean
@Qualifier("defTransactionManager")
public PlatformTransactionManager defTransactionManager() {
    return new HibernateTransactionManager(defSessionFactory().getObject());
}

@Bean
@Qualifier("secondSessionFactory")
public LocalSessionFactoryBean secondSessionFactory() {
    LocalSessionFactoryBean sfb = new LocalSessionFactoryBean();
    sfb.setDataSource(secondDataSource());

    Properties props = new Properties();
    //...

    sfb.setHibernateProperties(props);
    sfb.setPackagesToScan("my.package.subpackage");

    return sfb;
}

@Bean
@Qualifier("secondTM")
public PlatformTransactionManager secondTransactionManager() {
    return new HibernateTransactionManager(secondSessionFactory().getObject());
}
}

我的意图是使用带有两个事务管理器的注释事务。像这样注释的方法

@Transactional
public void method() {}

应该由 defTransactionManager 处理

和这样注释的方法

@Transactional("secondTM")
public void anotherMethod() {}

由 secondTransactionManager

defTransactionManager 工作正常,但是当涉及到 anotherMethod() 我得到:

org.hibernate.HibernateException: No Session found for current thread

当我对另一个方法(自动连接 secondSessionFactory,使用 TransactionTemplate)使用编程事务管理时,一切正常。

4

2 回答 2

1

如果@EnableTranscationManagement Spring 将使用按类型查找,您可以为单个事务管理器提供自己的查找方法,但它不适用于两个 tx 管理器

如果要检查 Spring 如何确定要执行的事务,可以尝试调试TransactionAspectSupport类。关键方法是setTransactionManagerBeanNamedetermineTransactionManager

于 2012-08-06T13:04:04.887 回答
1

以防万一有人遇到这个问题,我找到了解决方案:

@Configuration
@EnableTransactionManagement
@DependsOn("myTxManager")
@ImportResource("classpath:applicationContext.xml")
public class AppConfig implements TransactionManagementConfigurer {

@Autowired
private PlatformTransactionManager myTxManager;

...

@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
    return this.myTxManager;
}

通过这种方式,您可以使用在 xml 配置中定义的特定 txManager。

如果您想定义在服务级别使用的txManager,您应该从类中删除@EnableTransactionManagement注释并在注释中@Configuration指定txManager@Transactional,例如

@Service
@Transactional(value="myTxManager", readOnly = true)
public class MyServiceImpl implements MyService { ... }
于 2014-09-17T08:01:03.900 回答