这个异常已经纠结好几天不能解决了,SSH项目更换高版本的mydsql就报乐观锁异常?怎么解决啊?

颖辉小居 发布于 2017/01/09 10:29
阅读 577
收藏 1

一个SSH项目

Spring3  Hibernate3.3.2 Struts2  mysql5.0

以前运行是正常的 ,现在要求数据库换成mysql5.6+

我把之前数据库的建表语句和初始数据导出来,再导入到新的数据库(使用navicat for mysql导入没有错误)

可是正常启动后,只要有插入或修改数据操作时,就会报错:

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.pl.domain.Stage#402881455972d669015972e334680006]
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1782)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2425)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2325)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2625)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:558)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:319)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)

本项目在Hibernate的映射文件和数据表中使用了数据版本字段:version。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.pl.domain.Game" table="game">
        <id name="id" type="java.lang.String">
            <column name="id" />
            <generator class="uuid" />
        </id>
        <timestamp name="version" column="version"></timestamp>
        <many-to-one name="rule" class="com.pl.domain.Rule" fetch="select">
            <column name="rid" />
        </many-to-one>
        <many-to-one name="level" class="com.pl.domain.Level" fetch="select">
            <column name="level" />
        </many-to-one>
        <many-to-one name="gametype" class="com.pl.domain.Type" fetch="select">
            <column name="gametype" />
        </many-to-one>
        <many-to-one name="gamesystem" class="com.pl.domain.Type" fetch="select">
            <column name="gamesystem" />
        </many-to-one>
        <many-to-one name="city" class="com.pl.domain.City" fetch="select">
            <column name="city" />
        </many-to-one>
        <many-to-one name="pgame" class="com.pl.domain.Game" fetch="select">
            <column name="pid" />
        </many-to-one>
        <property name="entry" type="java.lang.Integer">
            <column name="entry" length="1" />
        </property>
        <property name="createtime" type="java.util.Date">
            <column name="createtime"/>
        </property>
        <property name="way" type="java.lang.Integer">
            <column name="way" length="1" />
        </property>
        <property name="no" type="java.lang.String">
            <column name="NO" length="20" />
        </property>
        <property name="unit" type="java.lang.String">
            <column name="unit" length="225" />
        </property>
        <property name="reward" type="java.lang.String">
            <column name="reward" length="225" />
        </property>
        <property name="name" type="java.lang.String">
            <column name="name" length="20" />
        </property>
        <property name="startdate" type="java.util.Date">
            <column name="startdate" length="10" />
        </property>
        <property name="enddate" type="java.util.Date">
            <column name="enddate" length="10" />
        </property>
        <property name="status" type="java.lang.Integer">
            <column name="status" />
        </property>
        <property name="aim" type="java.lang.String">
            <column name="aim" length="65535" />
        </property>
        <property name="vision" type="java.lang.Integer">
            <column name="vision"  />
        </property>
        <property name="rankrule" type="java.lang.String">
        	<column name="rankrule"/>
        </property>
        <property name="grouprule" type="java.lang.String">
        	<column name="grouprule"/>
        </property>
        <property name="mf" type="java.lang.String">
        	<column name="mf"/>
        </property>
        <property name="ml" type="java.lang.String">
        	<column name="ml"/>
        </property>
        <property name="nf" type="java.lang.String">
        	<column name="nf"/>
        </property>
        <property name="nl" type="java.lang.String">
        	<column name="nl"/>
        </property>
        <property name="nif" type="java.lang.String">
        	<column name="nif"/>
        </property>
        <property name="nil" type="java.lang.String">
        	<column name="nil"/>
        </property>
        <property name="outtitle" type="java.lang.Integer">
        	<column name="outtitle"/>
        </property>
        <property name="isleague" type="java.lang.Integer">
        	<column name="isleague"/>
        </property>
        <property name="ispause" type="java.lang.Integer">
        	<column name="ispause"/>
        </property>
        <set name="stages" cascade="all" inverse="true" lazy="false">
            <key>
                <column name="gid" />
            </key>
            <one-to-many class="com.pl.domain.Stage" />
        </set>
    </class>
</hibernate-mapping>

网上查的好像是乐观锁定失败,可是网上别人的错误原因跟我的情况不一样, 不知道怎么解决:

这个是spring的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    <!--Properties Config Post Processor-->
	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location"
			value="/WEB-INF/Configuration.properties" />
	</bean>
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="${jdbc.driverClass}">
		</property>
		<property name="jdbcUrl">
			<value>${jdbc.url}</value>
		</property>
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<!-- 连接池中保留的最小连接数。 -->
		<property name="minPoolSize">
			<value>10</value>
		</property>

		<!-- 连接池中保留的最大连接数。Default:15 -->
		<property name="maxPoolSize">
			<value>10</value>
		</property>

		<!-- 初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
		<property name="initialPoolSize">
			<value>5</value>
		</property>


		<!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
		<property name="maxIdleTime">
			<value>60</value>
		</property>

		<!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
		<property name="acquireIncrement">
			<value>5</value>
		</property>


		<!--
			1. JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 2.
			属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
			如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0
		-->
		<property name="maxStatements">
			<value>0</value>
		</property>

		<!-- 每60秒检查所有连接池中的空闲连接。Default: 0 -->
		<property name="idleConnectionTestPeriod">
			<value>60</value>
		</property>

		<!-- 定义在从数据库获取新连接失败后重复尝试的次数 Default: 30 -->
		<property name="acquireRetryAttempts">
			<value>30</value>
		</property>


		<!--
			1. 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 2.
			保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
			获取连接失败后该数据源将申明已断开并永久关闭。Default: false
		-->
		<property name="breakAfterAcquireFailure">
			<value>true</value>
		</property>

		<!--
			1. 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 2.
			保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
			获取连接失败后该数据源将申明已断开并永久关闭。Default: false
		-->
		<property name="testConnectionOnCheckout">
			<value>false</value>
		</property>
	</bean>
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<!-- 批处理 -->
				<prop key="hibernate.jdbc.batch_size">5</prop>
				<!-- 开启缓存 -->
				<prop key="hibernate.cache.provider_class">
					org.hibernate.cache.EhCacheProvider
				</prop>
				<prop key="cache.use_second_level_cache">true</prop>
			</props>
		</property>
		<property name="mappingDirectoryLocations">
			<list>
				<value>classpath:/com/pl/domain</value>			
			</list>
		</property>
	</bean>
	<bean id="tdataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		
		<property name="driverClass" value="${jdbc.driverClass}">
		</property>
		<property name="jdbcUrl">
			<value>${jdbc.turl}</value>
		</property>
		<property name="user" value="${jdbc.tusername}"></property>
		<property name="password" value="${jdbc.tpassword}"></property>
		<property name="minPoolSize">
			<value>5</value>
		</property>
		<property name="maxPoolSize">
			<value>10</value>
		</property>
		<property name="initialPoolSize">
			<value>1</value>
		</property>
		<property name="maxIdleTime">
			<value>60</value>
		</property>
		<property name="acquireIncrement">
			<value>5</value>
		</property>
		<property name="maxStatements">
			<value>0</value>
		</property>
		<property name="idleConnectionTestPeriod">
			<value>60</value>
		</property>
		<property name="acquireRetryAttempts">
			<value>30</value>
		</property>
		<property name="breakAfterAcquireFailure">
			<value>true</value>
		</property>
		<property name="testConnectionOnCheckout">
			<value>false</value>
		</property>
	</bean>
	<bean id="tsessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="tdataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<!-- 批处理 -->
				<prop key="hibernate.jdbc.batch_size">5</prop>
				<!-- 开启缓存 -->
				<prop key="hibernate.cache.provider_class">
					org.hibernate.cache.EhCacheProvider
				</prop>
				<prop key="cache.use_second_level_cache">true</prop>
			</props>
		</property>
		<property name="mappingDirectoryLocations">
			<list>
				<value>classpath:/com/pl/domain</value>			
			</list>
		</property>
	</bean>
	<!-- 事务处理设置 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
	</bean>
	<bean id="ttransactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="tsessionFactory" />
		</property>
	</bean>

	<!-- 所有方法使用PROPAGATION_REQUIRED类型的事务 -->
	<bean id="interceptorTransaction"
		class="org.springframework.transaction.interceptor.TransactionInterceptor">
		<property name="transactionManager">
			<ref local="transactionManager" />
		</property>
		<property name="transactionAttributes">
			<props>
				<prop key="*">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>
	<bean id="tinterceptorTransaction"
		class="org.springframework.transaction.interceptor.TransactionInterceptor">
		<property name="transactionManager">
			<ref local="ttransactionManager" />
		</property>
		<property name="transactionAttributes">
			<props>
				<prop key="*">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>

	<!-- 管理所有以Service结尾的Bean -->
	<bean
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="beanNames">
			<list>
				<value>*Service</value>
			</list>
		</property>
		<property name="interceptorNames">
			<list>
				<value>interceptorTransaction</value>
				<value>tinterceptorTransaction</value>
				<value>interceptoruploadTransaction</value>
			</list>
		</property>
	</bean>
	
	<!-- 服务器datasource -->
	<bean id="sessionFactorymain"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource1" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">false</prop>
				<prop key="hibernate.cglib.use_reflection_optimizer">false</prop>
				<prop key="hibernate.jdbc.fetch_size">50</prop>
				<prop key="hibernate.jdbc.batch_size">20</prop>
			</props>
		</property>
		<property name="mappingDirectoryLocations">
			<list>
				<value>classpath:/com/pl/pojo</value>			
			</list>
		</property>
	</bean>
	<bean id="transactionuploadManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="sessionFactorymain" />
		</property>
	</bean>
	<bean id="interceptoruploadTransaction"
		class="org.springframework.transaction.interceptor.TransactionInterceptor">
		<property name="transactionManager">
			<ref local="transactionuploadManager" />
		</property>
		<property name="transactionAttributes">
			<props>
				<prop key="*">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>
	<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="${jdbc.driverClass}">
		</property>
		<property name="jdbcUrl">
			<value>${jdbc.url}</value>
		</property>
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="minPoolSize">
			<value>5</value>
		</property>
		<property name="maxPoolSize">
			<value>10</value>
		</property>
		<property name="initialPoolSize">
			<value>5</value>
		</property>
		<property name="maxIdleTime">
			<value>60</value>
		</property>
		<property name="acquireIncrement">
			<value>5</value>
		</property>
		<property name="maxStatements">
			<value>0</value>
		</property>
		<property name="idleConnectionTestPeriod">
			<value>60</value>
		</property>
		<property name="acquireRetryAttempts">
			<value>30</value>
		</property>
		<property name="breakAfterAcquireFailure">
			<value>true</value>
		</property>
		<property name="testConnectionOnCheckout">
			<value>false</value>
		</property>
	</bean>
</beans>



加载中
0
颖辉小居
颖辉小居

经过3天欲仙欲死爬坑,自己已经解决了这个问题。

记录到博客中:https://my.oschina.net/iyinghui/blog/822592

魔力猫
魔力猫
好多早年不规范埋的雷。
0
mark35
mark35
SSH+mysql == 连环坑
颖辉小居
颖辉小居
回复 @mark35 : 已经把驱动 从5.0 换成5.1了,以前的5.0 还有其他错误。
mark35
mark35
先查查是不是jar驱动包需要更新了
mark35
mark35
回复 @颖辉小居 : 没有快速、低成本的解决办法。本来维护别人的(老)项目就是坑,再加上java+mysql的组合那就是烫手山芋了
颖辉小居
颖辉小居
这个是公司刚刚交到我手里的项目,已经用了好几年了,现在就要换mysql到5.6 请问这个错误有什么办法解决呢?
0
宏哥
宏哥

引用来自“mark35”的评论

SSH+mysql == 连环坑

哈哈

mysqler居然想做事务隔离

太监想F K

jack984
jack984
回复 @mark35 : 你的意思是不是小公司,如果换用php+postgresql就可以傻瓜式运行,在代码和设计上不用怎么操心,就能轻松应付很多年的稳定运行。在此特请教具体做法.
mark35
mark35
小公司玩java(ssh)+mysql实现高级功能(高并发、高级事务、多表联合操作、大事务)就是个死字,要么开发人员被坑死,要么公司被拖死~~
0
雨翔河
雨翔河
5.6多了好多限制,如时间不能为0,否则会出错的。
颖辉小居
颖辉小居
会报这个错误:1067 - Invalid default value for 'version' 但是可以修改mysql的配置文件允许时间类型默认值为0. 删除配置中的sql-mode 的 NO_ZERO_DATE重启mysql就可以了。
返回顶部
顶部