1

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)同じ呼び出しを再度実行する=>変更されたデータを取得する

4

1 に答える 1

0

connection.setAutoCommit(false)に戻った後、コミットを実行しないように見えるということですconnection.setAutoCommit(true)。したがって、アスペクトに次の行を追加した後、すべてが再び期待どおりに機能しました

try {
    connection.setAutoCommit(false);
    connection.setReadOnly(true);
    return pjp.proceed();
} catch (Throwable e) {
    return e;
} finally {
    // restore state
    connection.commit(); // THIS LINE
    connection.setReadOnly(readOnly);
    connection.setAutoCommit(autoCommit);
}
于 2013-03-19T14:43:14.700 に答える