mysql默认的隔离级别是可重复读。在一次会话当中,读操作了就不能写操作。
前提:web.xml中为了扩大session的作用范围,而使用了openSessionInView.导致了这一问题。
16:53:38,359 ERROR DefaultDispatcherErrorHandler:42 - Exception occurred during processing request: 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.
org.springframework.dao.InvalidDataAccessApiUsageException: 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.
at org.springframework.orm.hibernate5.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1126)
at org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:619)
at org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:616)
at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:341)
at org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:309)
at org.springframework.orm.hibernate5.HibernateTemplate.save(HibernateTemplate.java:616)
at com.pb.dao.impl.BaseDaoImpl.save(BaseDaoImpl.java:38)
at com.pb.service.impl.StaffServiceImpl.add(StaffServiceImpl.java:18)
at com.pb.web.action.StaffAction.add(StaffAction.java:24)
网上的解决方法是这样的,但是并未解决自己的问题,个人向觉得有问题:
①singleSession,问题出现的分身就是session的作用范围广。公用session,即读且写带来的数据库底层可重复读冲突
②既然console提示这样配置可以生效,那么就是配置被覆盖了,个人向理解为数据库提示覆盖了,后期补充,记录此处
<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>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
解决:在service层(事务操作主要就是针对这一层来进行操作的),通过事务配置改了只读属性
@Override
@Transactional(readOnly=false)
public void add(BcStaff staff) {
staffDao.save(staff);
}