卡尔·帕帕(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