Java Spring - 是否可以在同一个应用程序中使用多个事务管理器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4423125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:18:44  来源:igfitidea点击:

Spring - Is it possible to use multiple transaction managers in the same application?

javaspringjpaspring-transactionstransactionmanager

提问by Brian DiCasa

I'm new to Spring and I'm wondering if its possible to use numerous transaction managers in the same application?

我是 Spring 的新手,我想知道是否可以在同一个应用程序中使用多个事务管理器?

I have two data access layers - one for both of the databases. I'm wondering, how do you go about using one transaction managers for one layer and different transaction manager for the other layer. I don't need to perform transactions across both databases - yet. But I do need perform transactions on each database individually. I've created an image to help outline my problem:

我有两个数据访问层 - 一个用于两个数据库。我想知道,你如何为一层使用一个事务管理器,为另一层使用不同的事务管理器。我不需要跨两个数据库执行事务 - 还没有。但我确实需要单独对每个数据库执行事务。我创建了一个图像来帮助概述我的问题:

alt text

替代文字

Here is my application context configuration:

这是我的应用程序上下文配置:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:component-scan base-package="cheetah.repositories" />
    <tx:annotation-driven />

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="accounts" />
    </bean>

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <bean id="transactionManager"
        class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

</beans>

Here is an example that uses this configuration:

以下是使用此配置的示例:

@Repository
public class JpaAccountRepository implements AccountRepository {

    @PersistenceContext(unitName = "cheetahAccounts")
    private EntityManager accountManager;

    @Override
    @Transactional
    public Account findById(long id) {

        Account account = accountManager.find(Account.class, id);
        return account;
    }
}

So for the account repository, I want to use an entity manager factory with the persistence unit set to accounts. However, with my BusinessData Repository, I want to use an entity manager factory with a different persistence unit. Since I can only define one transaction manager bean, how can I go about using different transaction managers for the different repositories?

因此,对于帐户存储库,我想使用实体管理器工厂,并将持久性单元设置为帐户。但是,对于我的 BusinessData Repository,我想使用具有不同持久性单元的实体管理器工厂。由于我只能定义一个事务管理器 bean,我该如何为不同的存储库使用不同的事务管理器?

Thanks for any help.

谢谢你的帮助。

采纳答案by Chin Huang

Where you use a @Transactionalannotation, you can specify the transaction manager to useby adding an attribute set to a bean name or qualifier. For example, if your application context defines multiple transaction managers with qualifiers:

在使用@Transactional注释的地方,您可以通过将属性集添加到 bean 名称或限定符来指定要使用的事务管理器。例如,如果您的应用程序上下文定义了多个带有限定符的事务管理器:

<bean id="transactionManager1"
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory1" />
    <qualifier value="account"/>
</bean>

<bean id="transactionManager2"
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory2" />
    <qualifier value="businessData"/>
</bean>

You can use the qualifier to specify the transaction manager to use:

您可以使用限定符指定要使用的事务管理器:

public class TransactionalService {

    @Transactional("account")
    public void setSomethingInAccount() { ... }

    @Transactional("businessData")
    public void doSomethingInBusinessData() { ... }
}

回答by duffymo

This Spring Jira entry discusses the issue a bit:

这个 Spring Jira 条目讨论了这个问题:

https://jira.spring.io/browse/SPR-3955

https://jira.spring.io/browse/SPR-3955

I think it could be one transaction manager per connection if you're not using two-phase commit. You just need to create two transaction managers and inject them with the appropriate connection.

如果您不使用两阶段提交,我认为每个连接可能是一个事务管理器。您只需要创建两个事务管理器并为它们注入适当的连接。

But I must ask the question: why do you think you need two transaction managers? You can have more than one database connection. The DAOs that use the connections can and should be instantiated by different services, each of which can be annotated with their own transactional settings. One manager can accommodate both. Why do you think you need two?

但我必须问一个问题:为什么你认为你需要两个事务管理器?您可以拥有多个数据库连接。使用连接的 DAO 可以而且应该由不同的服务实例化,每个服务都可以用自己的事务设置进行注释。一位经理可以同时容纳两者。为什么你认为你需要两个?