spring事物不回滾的問題
一、環境介紹
mysql數據庫,springMVC,Mybatis,搭建完成測試過程中一個偶然的原因發現事物不回滾,立馬想到數據庫不支持。這個下面會有詳細說明。
二、mysql數據庫介紹
1.MyIsAm
1 靜態表
2 動態表
3 壓縮表
靜態表是默認的存儲格式,靜態表中的字段都是非變長的字段,
動態表的字段是變長的,優點是:佔用的空間相對較少,但是頻繁地更新刪除記錄會產生碎片,
壓縮表佔用磁盤空間小,每個記錄是被單獨壓縮的,所以只有非常小的訪問開支。
2.InnoDB
3.MEMORY
4.MERGE
三、解決方案
現在對mysql的存儲引擎有了解的話,那麼就知道如果你的表的存儲引擎方式是InnoDB的話,那麼不支持事物回滾就是你的配置問題了。下面是具體的解決方法
1.修改mysql的存儲引擎方式
更改方式1:修改配置文件my.cnf
修改完之後查看
2.配置方式
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
">
<!-- 配置數據源 使用的是Druid數據源 -->
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 初始化連接大小 -->
<property name="initialSize" value="0" />
<!-- 連接池最大使用連接數量 -->
<property name="maxActive" value="20" />
<!-- 連接池最小空閒 -->
<property name="minIdle" value="0" />
<!-- 獲取連接最大等待時間 -->
<property name="maxWait" value="60000" />
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="33" />
<!-- 用來檢測有效sql -->
<property name="validationQuery" value="${validationQuery}" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000" />
<!-- 打開removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分鐘 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 關閉abanded連接時輸出錯誤日誌 -->
<property name="logAbandoned" value="true" />
<!-- 監控數據庫 -->
<property name="filters" value="mergeStat" />
</bean>
<!-- myBatis文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 添加mybatis的配置 -->
<property name="configLocation" value="classpath:mybatis.xml"/>
<!-- 自動掃描entity目錄, 省掉Configuration.xml裏的手工配置 -->
<property name="mapperLocations" value="classpath:com/tanrice/dao/impl/*.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.tanrice.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 註解的方式配置事務 -->
<!-- 在需要的地方配置 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> -->
<!-- 註解方式配置事物 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="append*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="insert*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="update*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="modify*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="edit*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="delete*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="remove*" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="repair" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="delAndRepair" propagation="REQUIRED" isolation="READ_COMMITTED" />
<tx:method name="get*" propagation="SUPPORTS" isolation="READ_COMMITTED" />
<tx:method name="find*" propagation="SUPPORTS" isolation="READ_COMMITTED" />
<tx:method name="load*" propagation="SUPPORTS" isolation="READ_COMMITTED" />
<tx:method name="search*" propagation="SUPPORTS" isolation="READ_COMMITTED" />
<tx:method name="datagrid*" propagation="SUPPORTS" isolation="READ_COMMITTED" />
<tx:method name="*" propagation="SUPPORTS" isolation="READ_COMMITTED" />
</tx:attributes>
</tx:advice>
<!-- Spring aop事務管理 -->
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* com.tanrice.service..*Impl.*(..))" />
<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
</beans>
@Service
@Transactional
public class UserTaskServiceImpl implements UserTaskService{
public boolean updateUserTask(UserTask userTask,int id) {
boolean flag = false;
try{
flag = userTaskDao.saveUserTask(userTask)>0?true:false;
System.out.println("插入:"+flag);
flag = taskDao.updateTaskLeftcountById(id)>0?true:false;
System.out.println("修改:"+flag);
}catch(Exception e){
throw new RuntimeException();
}
return flag;
}
}
測試類
@org.junit.Test
public void testTrx(){
UserTask userTask = new UserTask();
userTask.setFullname("wanda");
userTask.setUserid(10071);
userTask.setTaskid(10026);
userTask.setGettime(new Date().getTime());
userTask.setState(5);
System.out.println("結果是:"+userTaskService.updateUserTask(userTask, 10026));
}
結果:在異常情況下,會回滾數據