Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java shiro会话更新:连接为只读。不允许导致数据修改的查询_Java_Spring_Session_Transactions_Shiro - Fatal编程技术网

Java shiro会话更新:连接为只读。不允许导致数据修改的查询

Java shiro会话更新:连接为只读。不允许导致数据修改的查询,java,spring,session,transactions,shiro,Java,Spring,Session,Transactions,Shiro,我们使用java SSH,最近我们经常遇到以下问题,不确定发生了什么,我搜索了这么多次,没有出现与shiro相关的场景,我们使用shiro作为身份验证框架,并自定义sessionDAO,包括“doCreate、doUpdate等”会话操作,甚至在applicationContext.xml中也可以这样配置: <tx:method name="do*" propagation="REQUIRES_NEW" /> <!-- C3P0 --> <bean

我们使用java SSH,最近我们经常遇到以下问题,不确定发生了什么,我搜索了这么多次,没有出现与shiro相关的场景,我们使用shiro作为身份验证框架,并自定义sessionDAO,包括“doCreate、doUpdate等”会话操作,甚至在applicationContext.xml中也可以这样配置:

 <tx:method name="do*" propagation="REQUIRES_NEW" /> 
 <!--  C3P0 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
        <property name="maxIdleTime" value="${cpool.maxIdleTime}"/> 
    </bean>        
  <!-- Spring jdbcTempate used for authentication -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
       <property name="dataSource" ref="dataSource"></property>  
   </bean>

    <!--SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>

        <property name="mappingLocations" value="classpath:com/shopping/web/entities/*.hbm.xml"></property>
        <property name="packagesToScan">  
            <list>  
                <value>com.shopping</value>  
            </list>  
        </property>
    </bean>

we use jdbctemplate together with hibernate5 with the same session managment.

    in db.proerties:
    jdbc.user=shopping
    jdbc.password=123456
    jdbc.driverClass=com.mysql.jdbc.Driver
  jdbc.jdbcUrl=jdbc:mysql://192.168.2.221:3306,192.168.2.222:3306,192.168.2.200:3306/shopping?useUnicode=true&characterEncoding=utf-8

    jdbc.initPoolSize=5
    jdbc.maxPoolSize=10
    cpool.maxIdleTime=25200

跟踪:

2018-01-22 18:02:03.482 [http-nio-8080-exec-762] INFO  org.apache.struts2.rest.RestActionInvocation - Executed action [//order/order!index!xhtml!200] took 574 ms (execution: 149 ms, result: 425 ms)
org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [update sessions set session=? where session_id=?]; Connection is read-only. Queries leading to data modification are not allowed; nested exception is java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
        at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:108)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:870)
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:931)
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:941)
        at com.shopping.web.authentication.dao.impl.ShiroSessionDao.doUpdate(ShiroSessionDao.java:48)
        at org.apache.shiro.session.mgt.eis.CachingSessionDAO.update(CachingSessionDAO.java:277)
        at org.apache.shiro.session.mgt.eis.CachingSessionDAO$$FastClassBySpringCGLIB$$2a5e5afd.invoke(<generated>)
2018-01-22 18:02:03.482[http-nio-8080-exec-762]INFO org.apache.struts2.rest.RestActionInvocation-执行的操作[//order/order!index!xhtml!200]耗时574毫秒(执行时间:149毫秒,结果:425毫秒)
org.springframework.dao.TransientDataAccessResourceException:PreparedStatementCallback;SQL[更新会话集会话=?其中会话id=?];连接是只读的。不允许导致数据修改的查询;嵌套异常为java.sql.SQLException:连接为只读。不允许导致数据修改的查询
位于org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:108)
位于org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
位于org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
位于org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
位于org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
位于org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:870)
位于org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:931)
位于org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:941)
在com.shopping.web.authentication.dao.impl.ShiroSessionDao.doUpdate(ShiroSessionDao.java:48)
位于org.apache.shiro.session.mgt.eis.CachingSessionDAO.update(CachingSessionDAO.java:277)
在org.apache.shiro.session.mgt.eis.CachingSessionDAO$$FastClassBySpringCGLIB$$2a5e5afd.invoke()上
有人能帮忙吗? 非常感谢

applicationContext.xml中的数据库配置:

 <tx:method name="do*" propagation="REQUIRES_NEW" /> 
 <!--  C3P0 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
        <property name="maxIdleTime" value="${cpool.maxIdleTime}"/> 
    </bean>        
  <!-- Spring jdbcTempate used for authentication -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
       <property name="dataSource" ref="dataSource"></property>  
   </bean>

    <!--SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>

        <property name="mappingLocations" value="classpath:com/shopping/web/entities/*.hbm.xml"></property>
        <property name="packagesToScan">  
            <list>  
                <value>com.shopping</value>  
            </list>  
        </property>
    </bean>

we use jdbctemplate together with hibernate5 with the same session managment.

    in db.proerties:
    jdbc.user=shopping
    jdbc.password=123456
    jdbc.driverClass=com.mysql.jdbc.Driver
  jdbc.jdbcUrl=jdbc:mysql://192.168.2.221:3306,192.168.2.222:3306,192.168.2.200:3306/shopping?useUnicode=true&characterEncoding=utf-8

    jdbc.initPoolSize=5
    jdbc.maxPoolSize=10
    cpool.maxIdleTime=25200

网上购物
我们使用jdbctemplate和hibernate5进行相同的会话管理。
在db.proerties中:
用户=购物
密码=123456
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://192.168.2.221:3306,192.168.2.222:3306192.168.2.200:3306/购物?使用Unicode=true&characterEncoding=utf-8
jdbc.initPoolSize=5
jdbc.maxPoolSize=10
cpool.maxIdleTime=25200

经过对这个问题的努力,我们找到了根本原因: 我们在服务器端使用mysql集群和c3p0连接池来存储数据以及shiro会话,如果池中没有可用的连接,有时网站需要重新连接mysql集群,一旦重新连接,默认模式为只读,但shiro会话需要在数据库中进行更新操作,这就导致了问题。 解决方案是:更改mysql连接url,如下所示: jdbc.jdbcUrl=jdbc:mysql://server1:3306,server2:3306,server3:3306/数据库?autoReconnectForPools=true&autoReconnect=true&failOverReadOnly=false&useUnicode=true&characterEncoding=utf-8
autoReconnectForPools=true&autoReconnect=true&failOverReadOnly=false是解决方案的关键

数据库连接的配置在哪里?您好,请参阅applicationContext.xml中有关数据库连接的以下配置: