問題描述
我們在項目中使用 Spring、Spring-Data 和 JPA.
We using Spring, Spring-Data and JPA in our project.
對于生產服務器,我們希望設置數據庫集群,以便所有讀取查詢都指向一臺服務器,所有寫入查詢都指向另一臺服務器.
For production servers, we would like to setup database cluster such that all read queries are directed to one server and all write queries are directed to another server.
這顯然需要對 DAO 的構建方式進行一些更改.
This obviously will require some changes in the way the DAOs are built.
如果到目前為止,有人一直使用 Spring-Data/JPA 遵循食譜風格的 DAO 創建,其中 DAO 實現負責讀取和寫入,那么有誰知道如何實現這一點?需要在架構上進行什么樣的更改來隔離這兩種類型的調用?
Does anyone know how to achieve this if one has, so far, been following cook-book style DAO creations using Spring-Data/JPA where a DAO implementation is responsible for both reads and writes? What kind of changes in architecture will be needed to segregate the two types of calls?
推薦答案
在使用 MySQL 時,Java 開發人員通常使用 Connector/J 作為 JDBC 驅動程序.開發者通常使用Connector/J com.mysql.jdbc.Driver
類,通過諸如jdbc:mysql://host[:port]/database
的URL 來連接到 MySQL 數據庫.
When using MySQL, it is common for Java developers to use Connector/J as the JDBC driver. Developers typically use the Connector/J com.mysql.jdbc.Driver
class, with a URL such as jdbc:mysql://host[:port]/database
to connect to MySQL databases.
Connector/J 提供了另一個名為 ReplicationDriver
允許應用程序在多個 MySQL 主機之間進行負載平衡.使用 ReplicationDriver
時,JDBC URL 更改為 jdbc:mysql:replication://master-host[:master-port][,slave-1-host[:slave-1-port]][,slave-2-host[:slave-2-port]]/database
.這允許應用程序連接到多個服務器之一,具體取決于在任何給定時間點可用的服務器.
Connector/J offers another driver called ReplicationDriver
that allows an application to load-balance between multiple MySQL hosts. When using ReplicationDriver
, the JDBC URL changes to jdbc:mysql:replication://master-host[:master-port][,slave-1-host[:slave-1-port]][,slave-2-host[:slave-2-port]]/database
. This allows the application to connect to one of multiple servers depending on which one is available at any given point in time.
使用 ReplicationDriver
時,如果 JDBC 連接設置為 read-only
,驅動程序會將 URL 中聲明的第一個主機視為 read-將
主機和所有其他主機寫入只讀
主機.開發人員可以通過如下構造他們的代碼在 Spring 應用程序中利用這一點:
When using the ReplicationDriver
, if a JDBC connection is set to read-only
, the driver treats the first host declared in the URL as a read-write
host and all others as read-only
hosts. Developers can take advantage of this in a Spring application by structuring their code as follows:
@Service
@Transactional(readOnly = true)
public class SomeServiceImpl implements SomeService {
public SomeDataType readSomething(...) { ... }
@Transactional(readOnly = false)
public void writeSomething(...) { ... }
}
這樣的代碼,每當readSomething
方法被調用時,Spring事務管理代碼都會獲取一個JDBCConnection
并調用setReadOnly(true)
code> 在它上面,因為服務方法默認使用 @Transactional(readOnly = true)
注釋.這將使來自 readSomething
方法的所有數據庫查詢轉到非主 MySQL 主機之一,以循環方式進行負載平衡.同樣,每當writeSomething
被調用時,Spring都會在底層的JDBCConnection
上調用setReadOnly(false)
,強制數據庫查詢到master服務器.
With code like this, whenever the method readSomething
is called, the Spring transaction management code will obtain a JDBC Connection
and call setReadOnly(true)
on it because the service methods are annotated with @Transactional(readOnly = true)
by default. This will make all database queries from the readSomething
method to go to one of the non-master MySQL hosts, load-balanced in a round-robin fashion. Similarly, whenever writeSomething
is called, Spring will call setReadOnly(false)
on the underlying JDBC Connection
, forcing the database queries to go to the master server.
這種策略允許應用程序將所有只讀流量定向到一組 MySQL 服務器,將所有讀寫流量定向到不同的服務器,而無需更改應用程序的邏輯架構或開發人員不必擔心不同的數據庫主機和角色.
This strategy allows the application to direct all read-only traffic to one set of MySQL servers and all read-write traffic to a different server, without changing the application's logical architecture or the developers having to worry about different database hosts and roles.
這篇關于Spring/J2EE Apps 中的只讀和讀寫分離的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!