JDBC复制驱动程序始终在没有活动缓存的情

时间:2013-03-18 17:49:35

标签: java mysql hibernate replication

我正在使用MySQL JDBC复制驱动程序com.mysql.jdbc.ReplicationDriver来转移主服务器和从服务器之间的负载。

我正在使用该连接网址

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注释所有readOnly请求。在我用所有服务层方法注释之前,即使他们可能互相调用。现在我只是注释请求方法而我是状态,我在第二次调用上获取数据库更新。

1)做初次通话=&gt;按预期获取数据

2)更改数据库中的数据

3)再次进行同样的呼叫=&gt;从第一次调用获得完全相同的数据

4)再次进行同样的呼叫=&gt;获取更改的数据

1 个答案:

答案 0 :(得分: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);
}