問題描述
我們?cè)陧?xiàng)目中使用 Spring、Spring-Data 和 JPA.
We using Spring, Spring-Data and JPA in our project.
對(duì)于生產(chǎn)服務(wù)器,我們希望設(shè)置數(shù)據(jù)庫(kù)集群,以便所有讀取查詢都指向一臺(tái)服務(wù)器,所有寫入查詢都指向另一臺(tái)服務(wù)器.
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.
這顯然需要對(duì) DAO 的構(gòu)建方式進(jìn)行一些更改.
This obviously will require some changes in the way the DAOs are built.
如果到目前為止,有人一直使用 Spring-Data/JPA 遵循食譜風(fēng)格的 DAO 創(chuàng)建,其中 DAO 實(shí)現(xiàn)負(fù)責(zé)讀取和寫入,那么有誰知道如何實(shí)現(xiàn)這一點(diǎn)?需要在架構(gòu)上進(jìn)行什么樣的更改來隔離這兩種類型的調(diào)用?
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 時(shí),Java 開發(fā)人員通常使用 Connector/J 作為 JDBC 驅(qū)動(dòng)程序.開發(fā)者通常使用Connector/J com.mysql.jdbc.Driver
類,通過諸如jdbc:mysql://host[:port]/database
的URL 來連接到 MySQL 數(shù)據(jù)庫(kù).
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 提供了另一個(gè)名為 ReplicationDriver
允許應(yīng)用程序在多個(gè) MySQL 主機(jī)之間進(jìn)行負(fù)載平衡.使用 ReplicationDriver
時(shí),JDBC URL 更改為 jdbc:mysql:replication://master-host[:master-port][,slave-1-host[:slave-1-port]][,slave-2-host[:slave-2-port]]/database
.這允許應(yīng)用程序連接到多個(gè)服務(wù)器之一,具體取決于在任何給定時(shí)間點(diǎn)可用的服務(wù)器.
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
時(shí),如果 JDBC 連接設(shè)置為 read-only
,驅(qū)動(dòng)程序會(huì)將 URL 中聲明的第一個(gè)主機(jī)視為 read-將
主機(jī)和所有其他主機(jī)寫入只讀
主機(jī).開發(fā)人員可以通過如下構(gòu)造他們的代碼在 Spring 應(yīng)用程序中利用這一點(diǎn):
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(...) { ... }
}
這樣的代碼,每當(dāng)readSomething
方法被調(diào)用時(shí),Spring事務(wù)管理代碼都會(huì)獲取一個(gè)JDBCConnection
并調(diào)用setReadOnly(true)
code> 在它上面,因?yàn)榉?wù)方法默認(rèn)使用 @Transactional(readOnly = true)
注釋.這將使來自 readSomething
方法的所有數(shù)據(jù)庫(kù)查詢轉(zhuǎn)到非主 MySQL 主機(jī)之一,以循環(huán)方式進(jìn)行負(fù)載平衡.同樣,每當(dāng)writeSomething
被調(diào)用時(shí),Spring都會(huì)在底層的JDBCConnection
上調(diào)用setReadOnly(false)
,強(qiáng)制數(shù)據(jù)庫(kù)查詢到master服務(wù)器.
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.
這種策略允許應(yīng)用程序?qū)⑺兄蛔x流量定向到一組 MySQL 服務(wù)器,將所有讀寫流量定向到不同的服務(wù)器,而無需更改應(yīng)用程序的邏輯架構(gòu)或開發(fā)人員不必?fù)?dān)心不同的數(shù)據(jù)庫(kù)主機(jī)和角色.
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.
這篇關(guān)于Spring/J2EE Apps 中的只讀和讀寫分離的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!