我正在使用 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)再次进行相同的调用=>获取更改的数据