简体   繁体   English

对 Spring 中的不同数据源(JdbcTemplate)重用相同的 @Transactional 方法

[英]Reusing same @Transactional method for different DataSources (JdbcTemplate) in Spring

we have this code where the same service method will call different daos each using a different datasource (and different JdbcTemplate s).我们有这段代码,其中相同的service方法将调用不同的daos ,每个使用不同的datasource (和不同的JdbcTemplate s)。 We would like to use @Transactional annotation, but as far as I know, this annotation is always linked to a specific TransactionManager (and thus, to a specific DataSource ).我们想使用@Transactional注释,但据我所知,这个注释总是链接到特定的TransactionManager (因此,链接到特定的DataSource )。

So, my question is, is there a way to choose dynamically which DataSource (or TransactionManager ) using when calling a @Transactional method so I can reuse that method to attack different databases?所以,我的问题是,有没有办法在调用@Transactional方法时动态选择使用哪个DataSource (或TransactionManager ),以便我可以重用该方法来攻击不同的数据库?

The @Transactional annotation doesn't allow dynamic evaluation of the value attribute which selects the TransactionManager (possibly by design, at least it doesn't look like it's going to change any time soon). @Transactional注释不允许对选择TransactionManagervalue属性进行动态评估(可能是设计使然,至少它看起来不会很快改变)。 So you can't have something like @Transactional("#{@getTxManager}") which would resolve the tx manager at call time.所以你不能有类似@Transactional("#{@getTxManager}")的东西,它会在调用时解析 tx 管理器。

In simple cases you might be able to get away with the following, but it would only be worth considering when for example you have a primary DS, and a secondary DS that's used only in some cases.在简单的情况下,您可能能够摆脱以下情况,但只有当您有一个主要 DS 和一个仅在某些情况下使用的辅助 DS 时才值得考虑。 Otherwise you'd be peppering the code that selects between calling foo/bar all around, and that wouldn't look clean at all否则你会在调用foo/bar之间选择代码,这看起来根本不干净

// TX boundary on the "top" abstraction layer
@Transactional("foo")
public void foo() {
    doWork();
}
@Transactional("bar")
public void bar() {
    doWork();
}

private void doWork() {
    // Work done here, no concern for tx management
}

For more complex cases like multitenancy, AbstractRoutingDataSource is an easy and robust choice if you haven't considered it yet.对于多租户等更复杂的情况,如果您尚未考虑, AbstractRoutingDataSource是一个简单而可靠的选择。 Although depending on how much switching you need, it may require tweaking or be even unsuitable.尽管取决于您需要多少切换,它可能需要调整甚至不合适。

Finally, you might be able to create your own annotation that does choose the DS dynamically (although I don't guarantee it), but that would be the riskiest approach for possible very little gains.最后,您也许可以创建自己的注释来动态选择 DS(尽管我不保证),但这将是风险最大的方法,可能收益很少。

The safest way for you would be to create separate services for each dao... I wouldn't like to be debugging such code.对您来说最安全的方法是为每个 dao 创建单独的服务......我不想调试这样的代码。 Think about maintaining this code and possible failures that might happen.考虑维护此代码以及可能发生的故障。

If I were you I'd ask myself following questions:如果我是你,我会问自己以下问题:

1.) Why separate dbs? 1.) 为什么要分开数据库?

2.) Isn't the context somehow mixed up? 2.) 上下文不是以某种方式混淆了吗? Maybe create some boundaries between them?也许在他们之间创造一些界限?

3.) Do my queries really need to be transactional? 3.) 我的查询真的需要是事务性的吗?

I probably don't know the context of your problem but for me it seems that you've modeled your application in a wrong way and I'd focus on it.我可能不知道您的问题的背景,但对我来说,您似乎以错误的方式为您的应用程序建模,我会专注于它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM