2016-09-10 15 views
1

Я хочу оптимизировать запросы на чтение, отправив их в базу данных только для чтения. Мой persistence.xml выглядит следующим образомКак перенаправить запросы выбора в реплицированную базу данных с использованием источника не-jta-данных в приложении Spring

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="appPU" transaction-type="JTA"> 
    <jta-data-source>jdbc/dbW</jta-data-source> 
    <non-jta-data-source>jdbc/dbR</non-jta-data-source> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 
    </persistence-unit> 
</persistence> 

jdbc/dbW точки dbWCP пула соединений (основной базе данных), и jdbc/dbR точек dbRCP пула подключений (только для чтения базы данных).

Я создал работающее приложение Java EE с следующей службой EJB:

@Stateless 
public class MyService { 
    @PersistenceContext 
    private EntityManager em; 


    public List<Person> findAll() { 
     return em.createQuery("SELECT p FROM Person p", Person.class).getResultList(); 
    } 

    public Person save(Person person) { 
     return em.persist(person); 
    } 
} 

Когда я называю findAll метод, запрос отправить только для чтения базы данных и, когда я звоню save метод он работает на основной базе данных. Но когда я настроил же с помощью Spring я получил следующее исключение:

Severe: RAR5029:Unexpected exception while registering component 

java.lang.IllegalStateException: Local transaction already has 1 non-XA Resource: cannot add more resources. 
    at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.enlistResource(JavaEETransactionManagerSimplified.java:345) 
    at com.sun.enterprise.resource.rm.ResourceManagerImpl.registerResource(ResourceManagerImpl.java:152) 
    at com.sun.enterprise.resource.rm.ResourceManagerImpl.enlistResource(ResourceManagerImpl.java:112) 
    at com.sun.enterprise.resource.pool.PoolManagerImpl.getResource(PoolManagerImpl.java:211) 
    at com.sun.enterprise.connectors.ConnectionManagerImpl.getResource(ConnectionManagerImpl.java:360) 

    at com.sun.enterprise.connectors.ConnectionManagerImpl.internalGetConnection(ConnectionManagerImpl.java:307) 
    at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:196) 
    at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:171) 
    at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:166) 
    at com.sun.gjc.spi.base.AbstractDataSource.getConnection(AbstractDataSource.java:114) 
    at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:123) 
    at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162) 
    at org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor.connectInternal(DatasourceAccessor.java:346) 
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.connectInternal(DatabaseAccessor.java:307) 
    at org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor.connect(DatasourceAccessor.java:434) 
    at org.eclipse.persistence.sessions.server.ConnectionPool.buildConnection(ConnectionPool.java:217) 
    at org.eclipse.persistence.sessions.server.ExternalConnectionPool.startUp(ExternalConnectionPool.java:146) 
    at org.eclipse.persistence.sessions.server.ServerSession.connect(ServerSession.java:493) 
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:742) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:239) 
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:685) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:204) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:304) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:336) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:302) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:462) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:633) 
    at com.sun.proxy.$Proxy322.createEntityManager(Unknown Source) 
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactoryUtils.java:285) 
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:255) 
    at com.sun.proxy.$Proxy323.createQuery(Unknown Source) 
    at pl.net.cb.MyService.findAll(MyService.java:17) 
    at pl.net.cb.MyService$$FastClassBySpringCGLIB$$985aba70.invoke(<generated>) 
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:280) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) 
    at pl.net.cb.MyService$$EnhancerBySpringCGLIB$$1c4f9d95.findAll(<generated>) 
    at pl.net.cb.web.HomeController.get(HomeController.java:23) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) 
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201) 
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175) 
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) 
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) 
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561) 
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) 
    at java.lang.Thread.run(Thread.java:745) 
Warning: RAR7132: Unable to enlist the resource in transaction. Returned resource to pool. Pool name: [ dbWCP ] 
Warning: RAR5117 : Failed to obtain/create connection from connection pool [ dbWCP ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: java.lang.IllegalStateException: Local transaction already has 1 non-XA Resource: cannot add more resources. 
Warning: RAR5114 : Error allocating connection : [Error in allocating a connection. Cause: java.lang.IllegalStateException: Local transaction already has 1 non-XA Resource: cannot add more resources. ] 
Severe: Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: java.lang.IllegalStateException: Local transaction already has 1 non-XA Resource: cannot add more resources. 
Error Code: 0 
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:316) 
    at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:135) 
    at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162) 
    at org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor.connectInternal(DatasourceAccessor.java:346) 
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.connectInternal(DatabaseAccessor.java:307) 
    at org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor.connect(DatasourceAccessor.java:434) 
    at org.eclipse.persistence.sessions.server.ConnectionPool.buildConnection(ConnectionPool.java:217) 
    at org.eclipse.persistence.sessions.server.ExternalConnectionPool.startUp(ExternalConnectionPool.java:146) 
    at org.eclipse.persistence.sessions.server.ServerSession.connect(ServerSession.java:493) 
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:742) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:239) 
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:685) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:204) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:304) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:336) 
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:302) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:462) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:633) 
    at com.sun.proxy.$Proxy322.createEntityManager(Unknown Source) 
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactoryUtils.java:285) 
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:255) 
    at com.sun.proxy.$Proxy323.createQuery(Unknown Source) 
    at pl.net.cb.MyService.findAll(OsobaService.java:17) 
    at pl.net.cbn.tutorial.db.connection.domain.model.osoba.OsobaService$$FastClassBySpringCGLIB$$985aba70.invoke(<generated>) 
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:280) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) 
    at pl.net.cb.MyService$$EnhancerBySpringCGLIB$$1c4f9d95.findAll(<generated>) 
    at pl.net.cb.web.HomeController.get(HomeController.java:23) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) 

Это мой конфигурационный файл:

@Configuration 
@ComponentScan(
     basePackages = "pl.net.cb", 
     excludeFilters = { 
      @ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) 
     } 
) 
@EnableTransactionManagement 
public class RootConfig { 
    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
     LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean(); 
     emfb.setPersistenceUnitName("appPU"); 
     final Properties properties = properties(); 
     emfb.setJpaProperties(properties); 
     return emfb; 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager() { 
     JtaTransactionManager transactionManager = new JtaTransactionManager(); 
     return transactionManager; 
    } 

    private Properties properties() { 
     Properties properties = new Properties(); 
     properties.setProperty("javax.persistence.schema-generation.database.action", "none"); 
     properties.setProperty("eclipselink.weaving", "false"); 
     properties.setProperty("eclipselink.logging.level.sql", "FINE"); 
     properties.setProperty("eclipselink.logging.parameters", "true"); 
     properties.setProperty("javax.persistence.validation.mode", "NONE"); 
     properties.setProperty("eclipselink.jdbc.batch-writing", "JDBC"); 
     properties.setProperty("eclipselink.jdbc.batch-writing.size", "10000"); 
     properties.setProperty("eclipselink.target-server", "SunAS9"); 
     return properties; 
    } 

} 

И моя служба:

@Service 
@Transactional 
public class MyService { 
    @PersistenceContext 
    private EntityManager em; 


    public List<Person> findAll() { 
     return em.createQuery("SELECT p FROM Person p", Person.class).getResultList(); 
    } 

    public Person save(Person person) { 
     return em.persist(person); 
    } 
} 

Когда я удалить <non-jta-data-source>jdbc/dbR</non-jta-data-source> линию от persistence.xml, тогда приложение Spring работает правильно, но всегда использует базу данных master.

Возможно ли использовать весеннее приложение с jta-data-source и non-jta-data-source так же, как приложение EJB? Как мне настроить такое поведение?

ответ

1

Я решил проблему, включив Non Transactional Connections для пула соединений только для чтения. dbRCP в консоли администратора домена Glassfish.

 Смежные вопросы

  • Нет связанных вопросов^_^