由于md文档部分hugo插件语法不兼容,建议访问作者网站查阅文章:wlizhi.cc
昨天给spring提了一个issue,这个问题在 声明式事务注意事项 中有描述过。
关于spring声明式事务传播行为 REQUIRES_NEW
,如果不做额外处理,可能会导致所有数据库连接被占用的问题。一直搞不明白,这里隐藏着很大的问题,为什么要有这个传播行为。于是就将问题提交给了spring官方。
当多个线程争用资源时,每个线程必须在结束任务之前抢占多个资源,这可能是一个隐患。因为此方法可能导致多个线程仅抢夺它们需要的部分资源,它们无法获得所需要的所有资源而释放所获得的东西。但是,到这个时候,资源已经用尽了。
spring声明式事务中的传播行为 REQUIRES_NEW
正是以上情况的表现。
最初提交的issue,我仅仅发了一段伪代码。内容如下:
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,讨论到此为止。
以下是原文:
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.
看到对方不耐烦了,考虑到自己说话方式的问题,一番思虑后,决定再回复一下。回复内容尽可能将这个潜在问题描述清楚。
回复如下:
Sorry, I didn't make it clear. This is the test code, where it blocks the real process. Methodb() will never execute.
百度翻译:抱歉,是我没有表达清楚。这是测试代码,它阻塞了整个进程。 methodB() 将永远不会执行。
示例代码:
@slf4j
@service
public class PropagationExampleServiceImpl implements PropagationExampleService {
@Autowired
PropagationExampleService service;
@Transactional
@Override
public</