MySQL JDBCレプリケーションドライバーcom.mysql.jdbc.ReplicationDriver
を使用して、マスターとスレーブの間で負荷をシフトしています。
その接続URLを使用しています
jdbc.de.url=jdbc:mysql:replication://master:3306,slave1:3306,slave2:3306/myDatabase?zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&roundRobinLoadBalance=true
アプリケーションを起動するとすぐに、データベースのロックされたスナップショットで作業しているように、アプリケーションが起動された場所からそのデータのみを取得します。CRUD操作を実行している場合、データを呼び出すことができないか、更新が表示されません。mysqlのレプリケーションは正常に機能しており、データベースから正しいデータを照会できます。
アクティブなレベル2キャッシュがなく、プールされた接続でHibernateを使用しています
通常のJDBCドライバーを使用している場合、com.mysql.jdbc.Driver
すべてが正常に機能しています。では、データベースで何を変更しても、なぜ常に同じ結果セットが得られるのでしょうか...
アップデート1
それは私の側面に関連しているようです
@Aspect
public class ReadOnlyConnectionInterceptor implements Ordered {
private class ReadOnly implements ReturningWork<Object> {
ProceedingJoinPoint pjp;
public ReadOnly(ProceedingJoinPoint pjp) {
this.pjp = pjp;
}
@Override
public Object execute(Connection connection) throws SQLException {
boolean autoCommit = connection.getAutoCommit();
boolean readOnly = connection.isReadOnly();
try {
connection.setAutoCommit(false);
connection.setReadOnly(true);
return pjp.proceed();
} catch (Throwable e) {
//if an exception was raised, return it
return e;
} finally {
// restore state
connection.setReadOnly(readOnly);
connection.setAutoCommit(autoCommit);
}
}
}
private int order;
private EntityManager entityManager;
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return order;
}
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Around("@annotation(readOnlyConnection)")
public Object proceed(ProceedingJoinPoint pjp,
ReadOnlyConnection readOnlyConnection) throws Throwable {
Session hibernateSession = entityManager.unwrap(Session.class);
Object result = hibernateSession.doReturningWork(new ReadOnly(pjp));
if (result == null) {
return result;
}
//If the returned object extends Throwable, throw it
if (Throwable.class.isAssignableFrom(result.getClass())) {
throw (Throwable) result;
}
return result;
}
}
すべてのreadOnlyリクエストに。でアノテーションを付けます@ReadOnlyConnection
。以前は、すべてのサービスレイヤーメソッドに、相互に呼び出している可能性があるとしても、それで注釈を付けていました。現在、リクエストメソッドにアノテーションを付けているだけで、 2回目の呼び出しでデータベースの更新を取得している状態になっています。
1)最初の呼び出しを行う=>期待どおりにデータを取得する
2)データベース内のデータの変更
3)同じ呼び出しを再度実行する=>最初の呼び出しからまったく同じデータを取得する
4)同じ呼び出しを再度実行する=>変更されたデータを取得する