卡尔·帕帕(Carl Papa)在Spring框架中使用方面来确定要使用的DataSource
(读写或只读)启发了我。 所以,我正在写这篇文章。
我必须承认,我对Spring的AbstractRoutingDataSource
早已熟悉。 但是我不知道在哪里可以使用它。 感谢卡尔和团队,以及他们的项目之一。 现在,我知道了一个很好的用例。
@交易
在Spring中,只读事务通常带有注释。
public class ... {@Transactional(readOnly=true)public void ...() {...}@Transactional // read-writepublic void ...() {...}
}
为了利用这一点,我们使用Spring的TransactionSynchronizationManager
来确定当前事务是否为只读。
AbstractRoutingDataSource
在这里,如果当前事务是只读的,我们使用Spring的AbstractRoutingDataSource
路由到只读副本。 否则,它将路由到默认主机。
public class ... extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {if (TransactionSynchronizationManager.isCurrentTransactionReadOnly() ...) {// return key to a replica}return null; // use default}...
}
使用上述方法后,我们发现TransactionSynchronizationManager
落后了一步,因为Spring 在建立同步之前已经调用了DataSource.getConnection()
。 因此, LazyConnectionDataSourceProxy
需要配置LazyConnectionDataSourceProxy
。
在讨论这个问题时,我们发现是否存在另一种方法来确定当前事务是否为只读(无需使用LazyConnectionDataSourceProxy
)。 因此,我们提出了一种实验方法,其中一个方面将TransactionDefinition
(来自@Transactional
批注,如果有的话)捕获为线程局部变量,以及一个AbstractRoutingDataSource
根据捕获的信息进行路由。
相关源代码可以在GitHub上找到 。 再次感谢, 卡尔 ! 顺便说一句, 卡尔也是获奖电影导演。 哇,才华横溢。
翻译自: https://www.javacodegeeks.com/2018/01/datasource-routing-spring-transactional.html