1

我正在使用 MySQL JDBC 复制驱动程序com.mysql.jdbc.ReplicationDriver在 Master 和 Slave 之间转移负载。

我正在使用该连接 URL

jdbc.de.url=jdbc:mysql:replication://master:3306,slave1:3306,slave2:3306/myDatabase?zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&roundRobinLoadBalance=true

一旦我启动我的应用程序,我只会从它启动的地方获取数据,就像我正在处理数据库的锁定快照一样。如果我正在执行任何 CRUD 操作,则数据不可调用或不显示更新。mysql 的复制工作得很好,我可以从数据库中查询正确的数据。

没有二级缓存处于活动状态,我正在使用带有池连接的休眠

如果我使用的是普通的 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;
}
}

我用@ReadOnlyConnection. 在我对所有服务层方法进行注释之前,即使它们可能会相互调用。现在我只对请求方法进行注释,并且我处于状态,我在第二次调用时获取数据库更新。

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 回答