InvalidDataAccessApiUsageException:Write operations are not allowed in read-only mode (FlushMode.NEV

错误截图:
不能在只读模式下进行写操作
错误描述:
org.springframework.dao.InvalidDataAccessApiUsageException:Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove ‘readOnly’ marker from transaction definition.

尝试了以下三种方法
1、修改web.xml的配置,添加:flushMode为true

 <filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
      <param-name>sessionFactoryBeanName</param-name>
      <param-value>mySessionFactory</param-value>
    </init-param>
      <init-param>
      <param-name> flushMode </param-name
      <param-value>AUTO</param-value> 
    </init-param>

  </filter>

2、或者在spring_hibernate_cfg.xml配置文件中设置read-only=”false”

<aop:config>
   <aop:pointcut id="bussinessService" expression="execution(* com.fan.service.base.*.*(..))" />
   <aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" />
 </aop:config>

 <tx:advice id="txAdvice" transaction-manager="txManager">
   <tx:attributes>
     <tx:method name="get*" read-only="false" propagation="NOT_SUPPORTED"/>
     <tx:method name="find*" read-only="false" propagation="NOT_SUPPORTED"/>
     <tx:method name="save*" propagation="REQUIRED"/> 
     <tx:method name="update*" propagation="REQUIRED"/>
     <tx:method name="delete*" propagation="REQUIRED"/>
   </tx:attributes>
 </tx:advice> 

3、或者在BaseDao的相应方法处添加

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW )

均没有解决该问题,如果项目较大的话,改配置文件影响很大,不建议用修改配置文件的方式进行处理,该问题最后找到的原因是:
在getXX()方法中调用了saveXX()方法,因为上层方法getXX()是只读的,所以在方法体内的方法都默认是只读的,即使saveXX()不是只读的也无效。
修改方式:将saveXX()的所有上层方法都修改为spring配置文件中拥有read-only=”false”方法名开头,例如:
配置文件:

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>     
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="check*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="exchange*" propagation="REQUIRED" />           
            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>

则将方法getXX()更改为exchangeXX()就可以解决这个问题。

猜你喜欢

转载自blog.csdn.net/Ling1604/article/details/72928044