spring整合问题分析之Write operations are not allowed in readonly 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"

1
2
3
4
5
<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

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 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..*.*(..)) 即可

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

1
@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即可

原文地址:https://www.cnblogs.com/roak/p/14532449.html