A method that opens a transaction calls another method that starts a new transaction,if all connections are exhausted before the last new transaction method is executed,then all threads in the process will block,this process will fail.
Pseudo code:
@Transactional
methodA(){
// All the threads that started the transaction were executed here, but the connection was exhausted.
// The latter method execution will get a new connection,but it will never get it.
@Transactional(propagation=Propagation.REQUIRES_NEW)
methodB(){
}
}
刚开始对方并没有认真的查看,仅回复What's the problem?。之后数次的回复貌似不在一个频道。也许是因为沟通时礼貌的原因、又或者是我问题描述的不够清楚。经过几次沟通后,差点把对方惹毛了,对方回复道:这里不是论坛,如果您认为是错误,请粘贴测试用例,如果您认为是改进,请提交PR,讨论到此为止。
以下是原文:
1
It's not forum here, if you think it's a bug please paste test case, if you think it's an improvement please submit PR, end of discussion.
spring:
datasource:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
druid:
max-active: 10
Here is the log:
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-1] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-2] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-5] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-6] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-8] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-9] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-3] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [ool-1-thread-10] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-7] c.j.s.s.i.PropagationExampleServiceImpl : methodA
2020-12-11 10:15:56.385 INFO 10864 --- [pool-1-thread-4] c.j.s.s.i.PropagationExampleServiceImpl : methodA
好吧,对方以为是我使用过程遇到了问题,在像他求助,回复道:
1
2
I think the result is expected, you should increase max-active > concurrency, so If you change max-active to 21, it will pass, waiting for your confirmation.
You should set a max-wait on dataSource, then getConnection will timeout instead of endless blocking.
I know, I just want to express that. In fact, the number of connections in the connection pool is generally not large. In the above example, only one layer is nested. If there are multiple layers of newly started transactions in the code, only a small amount of concurrency is needed to trigger the above result.
I just think that when multiple threads compete for resources, each thread must grab multiple resources before ending the task, which may be a hidden danger.
Because this method may cause multiple threads to rob only a part of the resources they need. They can't release what they have acquired without getting all the resources they need. By this time, however, resources have been exhausted.
Your test blocked because you didn't set timeout for ds.getConnection(), for example maxWait for druid and connectionTimeout for HikariCP.
It's really nothing to do with spring transaction.
I'm sorry to have taken you so long.
I just want to put forward what I think may be hidden dangers. It's not that I have encountered problems in use. I just don't quite understand why this place is designed in this way.
Even if Max wait is set here, the above situation may occur. It's just going to wait for a while, not the whole process, but it's bad enough.
For this reason, I choose to avoid using REQUIRES_NEW, if I need to start a new transaction in a method, I will use asynchronous or transactionSynchronization.afterCommit ()。
You may say that the outer method will not be able to sense the exception, but why should it? These are two transactions. If I need the outer layer to sense the inner layer's anomaly, I can use NESTED.
I admit your title "Propagation.REQUIRES_NEW May cause all connections to be occupied".
application should deal REQUIRES_NEW properly, there is no bug or improve space here, at most adding note in docs. Do you agree?