Ho un'applicazione Java che utilizza Spring/Hibernate (in esecuzione su Amazon Elastic Beanstalk) con un'istanza di Amazon RDS normale. Per distribuire il carico, aggiungo una replica di lettura. Ho scambiato il DB.url con la replica di lettura e ho testato un metodo che dovrebbe leggere solo i dati (i metodi non utilizzano sicuramente UPDATE, INSERT o DELETE). L'applicazione, tuttavia, restituisce errori.Come configurare Spring/Hibernate con MySQL Read-Replica
Le mie domande: Perché l'applicazione non funziona quando si leggono solo i dati? Come posso configurare Spring/Hibernate affinché funzioni con una replica di lettura?
I Dettagli:
L'errore che sto ottenendo è:
INFO: Internal error in method IEngageManager.getSimpleExamActivityLiveResults, ARGUMENTS=[
Credentials {
(m) password=0c2a765c057a31c51b68d0f6c75cef93,
(m) email=w1jg
}
]
com.iengage.exceptions.IEException: Internal error in method IEngageManager.getSimpleExamActivityLiveResults, ARGUMENTS=[
Credentials {
(m) password=0c2a765c057a31c51b68d0f6c75cef93,
(m) email=w1jg
}
]
at com.iengage.exceptions.ExceptionWrapper.overridingInvoke(ExceptionWrapper.java:25)
at com.iengage.springobjects.SingletonMethodInterceptor.invoke(SingletonMethodInterceptor.java:18)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
at com.iengage.managers.IEngageManager$$EnhancerByCGLIB$$c8a2c385.getSimpleExamActivityLiveResults(<generated>)
at com.iengage.services.IEngageService.getSimpleExamActivityLiveResults(IEngageService.java:379)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.sun.xml.ws.api.server.InstanceResolver$1.invoke(InstanceResolver.java:246)
at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:146)
at com.sun.xml.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:257)
at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:93)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:243)
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:444)
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:244)
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:135)
at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doGet(WSServletDelegate.java:129)
at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.doPost(WSServletDelegate.java:160)
at com.sun.xml.ws.transport.http.servlet.WSSpringServlet.doPost(WSSpringServlet.java:52)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:680)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
Il codice che chiama il DB:
public LecturerBO getLecturerByCode(Credentials credentials) {
return findSingleResultByCriteria(LecturerBO.class,Restrictions.eq("loginCode",credentials.getPassword()));
}
dove
protected <T> T findSingleResultByCriteria(Class<T> clazz, Criterion... criterion) {
Criteria crit = getSession().createCriteria(clazz);
for (Criterion c : criterion) {
crit.add(c);
}
return (T) crit.uniqueResult();
}
E per ultimo, la configurazione di Hibernate:
<bean id="generalManagerProxyTemplate"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="hibernateTransactionManager"/>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
<property name="preInterceptors">
<list>
<bean class="com.iengage.exceptions.ExceptionWrapper"/>
<bean class="com.iengage.utils.PerformanceLogger"/>
</list>
</property>
</bean>
<bean id="hibernateTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="pooledDataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="transaction.auto_close_session">true</prop>
<prop key="transaction.flush_before_completion">true</prop>
<prop key="show_sql">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
<property name="annotatedClasses">
<bean class="com.iengage.dao.EntityList"/>
</property>
</bean>
<bean id="pooledDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driverClassName}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="defaultAutoCommit" value="false"/>
<property name="testWhileIdle" value="true"/>
</bean>
<bean id="abstractDAO" class="com.iengage.dao.GeneralDAO" abstract="true">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="dataSource" ref="pooledDataSource"/>
</bean>
<bean id="dao" class="com.iengage.dao.IEngageDAO" parent="abstractDAO"/>
E per ultimo, come un controllo di integrità, mi collego con la lettura replica direttamente e tramite un semplice script che esegue le query SELECT che ho ospitato su un server di terze parti . Tutto ha funzionato come previsto.
Inoltre, nella mia ricerca prima di pubblicare questa domanda, la maggior parte delle risposte si concentrava sull'annotazione @Transactional
, che non viene utilizzata. Panda triste
Grazie per qualsiasi aiuto.
Stai omettendo la causa dell'eccezione generata? (ad esempio lanciando una nuova IEException senza il solito argomento gettabile?) – Vincent