问题描述:Service里的this.payBookMapper.insertFE20Data(targetMapMain);插入失败,则不回滚this.payBookMapper.insertFE20Item(targetItemMap);插入的记录
首先,Service里的方法代码如下,并且在Service类上面添加@Transactional
/**
* 缴款书开具
*/
@Override
public Map<String, Object> insertFSData(List<Map<String, Object>> fsdatalist) {
boolean flag = false;
String error_msg = "";
//循环校验数据
logger.info("***********缴款书开具开始************");
logger.info("请求报文:"+DataTypeConver.toJsonArray(fsdatalist));
/*for (Map<String, Object> map : fsdatalist) {
if (!_checkColumnInvalid(map) || !_checkDataInvalid(map) ||!_checkBusinessInvalid(map)) {
logger.info(message);
insertLog("2", message, map, "缴款确认", "");
return toListArrayResult(message);
}
}*/
String pay_code = "";
//循环保存数据
logger.info("开始插入缴款确认信息");
for (Map<String, Object> map : fsdatalist) {
pay_code = (String)map.get("pay_code");
Map<String,Object> targetMapMain = convertMapMain(map);
if(!targetMapMain.containsKey("afa050")) {
flag = true;
break;
}
//this.payBookMapper.insertFE20Data(convertMapMain(map));
//插入实时从表
List<Map<String,Object>> item_details = (List<Map<String,Object>>)map.get("item_details");
List<Map<String,Object>> details = new ArrayList<Map<String,Object>>();
for(int i=0;i<item_details.size();i++) {
Map<String,Object> itemMap = item_details.get(i);
itemMap.put("afc150", map.get("pay_code"));//主键
itemMap.put("afa050", targetMapMain.get("afa050"));//单位内码
itemMap.put("item_no", (i+1));
Map<String,Object> targetItemMap = convertMapItem(itemMap);
if(!targetItemMap.containsKey("afa030")) {
error_msg = "单位编码不存在";
flag = true;
break;
}
//收费项目错误
if(!targetItemMap.containsKey("afa260")) {
error_msg = "收费项目错误";
flag = true;
break;
}
this.payBookMapper.insertFE20Item(targetItemMap);
details.add(targetItemMap);
}
//计算校验码
String vcode = null;
targetMapMain.put("item_details", details);
try {
vcode = BillVerify.getInstance().getFullPayBillInfo(targetMapMain);
targetMapMain.put("afc183",vcode);
} catch (Exception e) {
e.printStackTrace();
}
//插入实时主表
//System.out.println("=================");
//System.out.println(targetMapMain.get("afc154") == null);
//System.out.println("null".equals(targetMapMain.get("afc154")));
//System.out.println(((JSONObject)targetMapMain.get("afc154")).isNullObject());
this.payBookMapper.insertFE20Data(targetMapMain);
//更新缴款书校验码
/*Map<String,Object> param = new HashMap<String,Object>();
param.put("afc150",targetMapMain.get("afc150"));
param.put("afc183",vcode); //校验码
this.payBookMapper.updateByPrimaryKeySelective(param); */
insertLog("1", message, map, "缴款书开具", "");
}
JSONObject msg = new JSONObject();
String code = "S0000";
if(flag) {
msg.put("pay_code", pay_code);
msg.put("security_code", error_msg);//单位编码不存在
code = "E0001";
}else {
msg.put("pay_code", pay_code);
msg.put("security_code", "0000");
logger.info("缴款书开具响应报文:"+toListArrayResult("S0000",msg.toString()));
}
return toListArrayResult(code,msg.toString());
}
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:jee="http://www.springframework.org/schema/jee"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-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/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd"
default-lazy-init="false">
<!--将针对注解的处理器配置好 -->
<context:annotation-config />
<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<!-- <context:component-scan base-package="com.mofit.fs.exchange" /> -->
<context:component-scan base-package="com.mofit.fs.exchange">
<!--将Controller的注解排除掉 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 引入jdbc配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!--创建jdbc数据源 -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="p6dataSource" class="com.p6spy.engine.spy.P6DataSource">
<constructor-arg>
<ref local="dataSource"/>
</constructor-arg>
</bean>
<!-- spring和MyBatis整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="p6dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
<!-- mybatis自动扫描加载Sql映射文件/接口 : MapperScannerConfigurer sqlSessionFactory
basePackage:指定sql映射文件/接口所在的包(自动扫描)
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mofit.fs.exchange"></property>
</bean>
<!-- 事务管理 : DataSourceTransactionManager dataSource:引用上面定义的数据源 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="p6dataSource"></property>
</bean>
<!-- 事务控制 -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
spring-mvc配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="false"
xmlns:task="http://www.springframework.org/schema/task"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!--将针对注解的处理器配置好 -->
<context:annotation-config />
<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<!-- <context:component-scan base-package="com.mofit.fs.exchange" /> -->
<context:component-scan base-package="com.mofit.fs.exchange" >
<!-- 扫描业务组件,让spring不扫描带有@Service注解的类,防止事务失效 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
<!-- 定时调用 -->
<task:annotation-driven scheduler="qbScheduler" mode="proxy" />
<task:scheduler id="qbScheduler" pool-size="10" />
<!-- 通过注解,把URL映射到Controller上,该标签默认注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->
<mvc:annotation-driven />
<!-- 定义跳转的文件的前后缀 ,视图模式配置-->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<!-- 配置前缀和后缀 -->
<property name="prefix" value="/view/" />
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 默认编码 -->
<property name="defaultEncoding" value="UTF-8" />
<!-- 文件大小最大值 -->
<property name="maxUploadSize" value="10485760000" />
<!-- 内存中的最大值 -->
<property name="maxInMemorySize" value="40960" />
</bean>
</beans>
如果spring-mvc里配置自动扫描Controller不排除Service,applicationContext.xml里自动扫描Service不排除Controller,则事务失效,错误的配置在上面文件的注释里。