Closed spring-projects-issues closed 3 years ago
s-mop commented
Yes, it is a problem when commit fails after the first commit is done, but Is there any suggested replacement workaround or other best practice to handle with multi-transaction scenario? for example different datasource or different data storages.Mark Paluch
Mark Paluch commented
From what I see the issue is rooted in how Spring's Transaction Manager works with synchronization. The initial assumption is, there's a single transaction manager that takes care of resources and synchronizations. Hence, all integrations interact with TransactionSynchronizationManager
which is backed by singleton ThreadLocals
. Since it never was required to qualify synchronizations and resources with an owing transaction manager, all of these are mixed and we're not able to sort out transactional resources.
Typically, transactional integrations bind their DataSource
(or other resources) to the transaction and do not care about the transaction manager. Looking at e.g. DataSourceTransactionManager
, the transaction manager is aware of the DataSource
while e.g. JdbcTemplate
is only aware of the DataSource
and not the transaction manager. Going further, DataSourceUtils.getConnecion(…)
binds a ConnectionSynchronization
to the transaction without the chance to know for which transaction manager the synchronization should apply
Kaushik commented
Yes. I am facing this issue in our project. But we use this heavily in our projects.
Just a quick search of public gihub repositories that use this class - https://github.com/search?q=%22org.springframework.data.transaction.ChainedTransactionManager%22&type=Code
Looking at the amount of usages, we need an alternate and much better approach to this
So what should we do when we need to use multiple DataSource
s in a single @Transactional
section? This was the simplest configuration when inconsistent rollbacks (i.e. one commits while another rolls-back) were not an issue. Can an example be provided?
So what should we do when we need to use multiple
DataSource
s in a single@Transactional
section? This was the simplest configuration when inconsistent rollbacks (i.e. one commits while another rolls-back) were not an issue. Can an example be provided?
+1 I am interested aswell.
I agree, deprecating stuff without providing a clear migration path (with examples before/after) is not cool
Introducing a utility that pretends to coordinate distributed transactions was wrong in the first place. Now folks are using ChainedTransactionManager
assuming that it does things correctly and wonder why there is no replacement.
A migration path can be that you go full-on XA and 2PC (e.g. using Atomikos Transaction Manager with JTA). Alternatively, you design your business code in a way that considers partially committed transactions. Since this is highly specific to your domain, Spring cannot help here.
assuming that it does things correctly
It does exactly what its documentation says it does, and that's why I'm using it. It's not your fault that people assume it does something else, and that's no reason to remove it.
Introducing a utility that pretends to coordinate distributed transactions was wrong in the first place. Now folks are using
ChainedTransactionManager
assuming that it does things correctly and wonder why there is no replacement.A migration path can be that you go full-on XA and 2PC (e.g. using Atomikos Transaction Manager with JTA). Alternatively, you design your business code in a way that considers partially committed transactions. Since this is highly specific to your domain, Spring cannot help here.
I wonder why you assume that I was assuming it does things "correctly". The javadoc is very clear that it does handle transactions separately so that one can commit and another one might fail. I designed my code for idempotence so I just need to retry the whole thing to pass the next time. This feature is useful because it is simple to use and the limitations were very well documented and not misleading at all.
I wonder why you assume
This is the reception on our side given the history of tickets and StackOverflow question that we have received. We suggest not using ChainedTransactionManager
. It can be useful in a niche but for the broader audience it is not a general-purpose TransactionManager
. We do not plan to extend or fix any bugs around ChainedTransactionManager
and it is no longer maintained. Therefore it is fair to mark it as deprecated.
If this utility works for your arrangement, you're free to copy that code into your codebase and use it as needed.
I do not want a global transaction manager across two sources. I want separate transaction managers for separate databases. However, I get bean collisions when I try to define two PlatformTransactionManagers for the different databases. They are never combined in a single transaction.
Mark Paluch opened DATACMNS-1817 and commented
ChainedTransactionManager
is the primary class inorg.springframework.data.transaction
that is used for multi-transactionmanager arrangements. It is useful to coordinate transactions across multiple resources especially when one transaction manager is a Spring one and the other is a foreign one.Over time, we found that we're basically emulating distributed transactions on a best-effort basis with known gaps. These gaps lead to inconsistencies or unexpected behavior during rollbacks. Part of the problem is that resource/synchronization storage is a singleton
ThreadLocal
. Using two transaction managers based onAbstractPlatformTransactionManager
causes the first transaction manager to handle all synchronizations regardless of their resource origin (primary and secondary transactional resources). If the second transaction manager commit fails, then already all synchronizations are processed and there's no way to recover.Therefore, we're going to deprecate
ChainedTransactionManager
and the entireorg.springframework.data.transaction
that hosts support classes for multi-transactionsIssue Links: