• spring整合问题分析之-Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.


    1.异常分析

    Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

    大概意思就是:在只读模式(FlushMode.MANUAL)中不允许写操作,将您的会话转换为FlushMode.COMMIT/AUTO或从事务定义中删除“readOnly”标记。

    2.分析原因:

    <1>.事务通知相应方法设置属性,read-only="true"

      <tx:advice id="txadvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="*" read-only="true"/>
            </tx:attributes>
        </tx:advice>
    

     此时dao层只可以执行,get,find,count(*)等查询操作,不可以执行cud 操作

    <2>.事务通知了相应方法添加事务,但是aop管理设置时切入点表达式却不包含该方法 ,则其read-only 默认为 true

    <!-- txadvice设置 --> 
            <tx:advice id="txadvice" transaction-manager="txManager">
                <tx:attributes>
                    <tx:method name="*" read-only="false"/>
                </tx:attributes>
            </tx:advice>
    <!--aop管理设置-->
    
            <aop:config>
    		<aop:pointcut expression="execution(* com.ssj..*.*())" id="myPointcut"/>//注意此处*.*()括号中为无参
    		<aop:advisor advice-ref="txadvice" pointcut-ref="myPointcut"/>
    	</aop:config>  
    

     注意:此处事务通知了所有方法添加事务,而切入点却只拦截了无参的方法.也就是说此时只有无参的构造方法是

            可以进行cud操作的,而有参的则不能.

     <3>.使用注解配置事务的时注解忘记添加也会抛出此异常

    <4>.使用扫描添加注解的时候导致覆盖

    例如:applicationContext.xml中com.ssj扫描全局添加注解之后,

      在springmvc.xml中又扫描一次com,ssj导致将applicationContext配置的事务覆盖,而且此配置文件中并没有相关事务的配置.从而出现此种异常

    3.解决方案

    针对原因一:将method 中read-only设置为false即可

    针对原因二:将切入点表达式完善为:execution(* com.ssj..*.*(..)) 即可

    针对原因三:在需要加事务的类上添加语句:

    @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
    

     注:在使用Spring代理时,默认只有在public可见度的方法的@Transactional 注解才是有效的,

      其它可见度(protected、private、包可见)的方法上即使有@Transactional 注解也不会应用这些事务属性的,Spring也不会报错,

      如果你非要使用非公共方法注解事务管理的话,可考虑使用AspectJ。

    针对原因四:在springmvc.xml中配置扫描范围的时候不要涉及到applicationContext.xml中配置的事务设置范围

    例如: applicationContext--->"execution(* com.ssj.service..*.*(..))" 给service包中的方法添加事务通知   注:使用@transaction注解时,同样

       springmvc.xml------><context:component-scan base-package="com.ssj.controller"></context:component-scan> 

               开启注解扫描的时候不要涉及到service包中的方法,只管理controller即可

  • 相关阅读:
    面向对象
    标准库内置模块
    json迭代器生成器装饰器
    基本数据操作
    列表元组字典字符串操作
    深入了解Spring之IoC
    认识OAuth 2.0及实例
    web.xml中context-param和init-param的区别
    虚拟机centos6网卡配置及提示Device does not seem to be present
    JUC之深入理解ReentrantReadWriteLock
  • 原文地址:https://www.cnblogs.com/ssjifm/p/7576648.html
Copyright © 2020-2023  润新知