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

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

我们有这段代码,其中相同的 service 方法将使用不同的 datasource(和不同的 JdbcTemplate)调用不同的 daos。我们想使用 @Transactional 注释,但据我所知,这个注释总是链接到特定的 TransactionManager(因此,链接到特定的 DataSource)。

所以,我的问题是,有没有办法在调用 @Transactional 方法时动态选择使用哪个 DataSource(或 TransactionManager),以便我可以重用该方法进行攻击不同的数据库?

对您来说最安全的方法是为每个 dao 创建单独的服务...我不想调试此类代码。考虑维护此代码以及可能发生的故障。

如果我是你,我会问自己以下问题:

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

2.) 上下文是不是搞混了?也许在它们之间创建一些界限?

3.) 我的查询真的需要事务性的吗?

我可能不知道你的问题的背景,但对我来说,你似乎以错误的方式为你的应用程序建模,我会关注它。

@Transactional 注释不允许 value 属性的 dynamic evaluation 选择 TransactionManager(可能是设计使然,至少它看起来不像它很快就会改变)。所以你不能有像 @Transactional("#{@getTxManager}") 这样的东西,它会在调用时解析 tx 管理器。

在简单的情况下,您也许可以避开以下问题,但只有当您有一个主 DS 和一个仅在某些情况下使用的辅助 DS 时才值得考虑。否则你会在调用 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
}

对于像多租户这样更复杂的情况,如果您还没有考虑过,AbstractRoutingDataSource 是一个简单而可靠的选择。尽管取决于您需要多少切换,但它可能需要调整甚至不合适。

最后,您可以创建自己的注释来动态选择 DS(尽管我不保证),但这是风险最高的方法,但收益可能很小。