我正在使用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
,一切正常。那么,为什么我总是得到相同的结果集,无论我在数据库中做了什么改变......
似乎与我的方面有关
@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;获取更改的数据
答案 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);
}