zl程序教程

您现在的位置是:首页 >  后端

当前栏目

spring中事务传播下,特殊方法手动控制事务

Spring控制方法事务 手动 特殊 传播
2023-09-14 09:04:40 时间
在开发中,遇到事务问题:从excel文件中解析导入数据,每个sheet页中的数据作为单个的事务单元提交数据库。解析下代码实现: 方法①:mainAnalysisEntrance(…)解析excel入口和权限和其他业务等处理; 方法②:analysisWorkbook(…)解析excel工作簿; 方法③:analysisPerSheet(…)解析每一个sheet页数据,并将其中通过的数

在开发中,遇到事务问题:从excel文件中解析导入数据,每个sheet页中的数据作为单个的事务单元提交数据库。解析下代码实现:

方法①:mainAnalysisEntrance(…)解析excel入口和权限和其他业务等处理;
方法②:analysisWorkbook(…)解析excel工作簿;
方法③:analysisPerSheet(…)解析每一个sheet页数据,并将其中通过的数据,作为一个事务单元,提交数据库;
方法④:analysisPerRow(…)解析excel中sheet中的每一行;
方法⑤:notSupportBatchAllDBByPerSheetDatas(…)此方法持久化sheet页数据.此方法手动单方法处理事务.

遇到问题:方法⑤每次都不会单独作为事务单元提交sheet页数据,等到方法③执行全部完成,才会提交所有sheet页数据,或全部回滚所有sheet页数据,违背一开始的当sheet页作为事务的提交方案。

简略代码附入:

……

import jxl.*;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.ApplicationContext;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import org.springframework.stereotype.Service;

import org.springframework.transaction.TransactionDefinition;

import org.springframework.transaction.TransactionStatus;

import org.springframework.transaction.interceptor.TransactionAspectSupport;

import org.springframework.transaction.support.DefaultTransactionDefinition;

@Service("smartImportService")

public class SmartImportServiceImpl implements SmartImportService {

 //log

 private static final Logger LOG = LoggerFactory.getLogger(LawCaseAllSmartImportSchemeServiceImpl.class);

 @Autowired

 private AMapper aMapper;

 @Autowired

 private ApplicationContext ctx;

 public JsonResult mainAnalysisEntrance(InputStream is, Object ... args) {

 Workbook book = Workbook.getWorkbook(is);

 return analysisWorkbook(book, args);

 public JsonResult analysisWorkbook(Workbook book, Object ... args) throws Exception{

 for(int sheetIndex = 0; sheetIndex allSheetCount; sheetIndex++){

 break;

 BusinessResult businessSheetResult = analysisPerSheet(sheet, args0);

 ……//finally中关闭

 book.close();

 return jsonResult;

 public BusinessResult analysisPerSheet(Sheet sheet, Object ... args) throws Exception{

 for(int rowIndex = 2; rowIndex rows; rowIndex++){

 Map String, Object rowRes = analysisPerRow(cells, args);

 Object [] objLists = new Object[6];

 //把当前sheet页中ok的数据持久化数据

 boolean db_res = notSupportBatchAllDBByPerSheetDatas(objLists);

 public Map String, Object analysisPerRow(Cell [] cells, Object ... args) throws Exception{

 //行数据验证和解析

 public boolean notSupportBatchAllDBByPerSheetDatas(Object ... lists){

 DataSourceTransactionManager txManager = (DataSourceTransactionManager) ctx.getBean("transactionManager");

 DefaultTransactionDefinition def = new DefaultTransactionDefinition();

 def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 事物隔离级别,开启新事务

 TransactionStatus txStatus = txManager.getTransaction(def);// 获得事务状态

 try {

 List AEntity aList = (List AEntity ) lists[0];

 if(aList != null !aList.isEmpty()){

 int aRows = aMapper.batchInsertA(aList);

 if(aRows != aList.size()){

 SmartImportSchemeAssist.printTrackingMsg(LOG, "批量插入每个sheet页中所有涉及到数据库的数据:A表,数据插入不一致,回滚事务.");

 // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //--此回滚为手动但失效,并且不推荐

 // return false;

 throw new RuntimeException();

 txManager.commit(txStatus);//事务处理成功,提交当前事务

 return true;

 } catch (Exception e) {

 SmartImportSchemeAssist.printErrMsg(LOG, "批量插入每个sheet页中所有涉及到数据库的数据操作异常,回滚事务.", e);

 txManager.rollback(txStatus);//事务处理失败,回滚当前事务

 return false;


public static void printErrMsg(Logger logger, String msg, Exception e){ logger.error("^-^ " + msg + e.getMessage(), e); * 打印非错误日志 * */ public static void printTrackingMsg(Logger logger, String msg){ logger.info("^.^ " + msg);
声明式事务配置:

 ?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"

 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd

 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd

 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd" 

 !-- import resource="applicationContext-activiti.xml"/ -- 

 bean id="transactionManager" 

 property name="dataSource" ref="dataSource" / 

 /bean 

 !-- 注解方式配置事物 -- 

 !-- aop:config aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(**..service..*.*(..))" order="1"/ /aop:config -- 

 aop:config 

 aop:pointcut expression="(execution(* com.a.service.*.* (..))) or (execution(* com.b.service.*.* (..))) or (execution(* com.c.service.*.* (..)))" id="pointcut" / 

 aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" / 

 /aop:config 

 !-- 事务控制 -- 

 tx:advice id="txAdvice" transaction-manager="transactionManager" 

 tx:attributes 

 !--只读,开启默认事务-- 

 tx:method name="get*" read-only="true" / 

 tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception" / 

 tx:method name="crud*" propagation="REQUIRED" rollback-for="java.lang.Exception" / 

 !-- 此配置未测试是否存在 -- 

 tx:method name="*" / 

 !--此前缀只读,非事务方式执行方法-- 

 tx:method name="notSupport*" propagation="NOT_SUPPORTED" read-only="true" / 

 /tx:attributes 

 /tx:advice 

 /beans 

好了,各个sheet也作为事务单元处理,1,2,3解析,2失败(事务失败),1,3成功进入数据库。



Spring boot 使用 ON DUPLICATE KEY UPDATE属性控制版本 更新数据不成功 如果更新不成功会报下面的错误(此错误是自定义的): The data you want to update has been updated by another user. Please reopen and try again! 一、主要按下面的流程检查: 1、检查数据库的段alastupdatetime定义 2、检查.xml的alastupdatetime 3、要更新数据的主键是否在同一个updateByBatch中的List中重复出现
Spring源码分析(九)lazy-init 在Spring中是怎么控制加载的 ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化(也就是依赖注入)。提前实例化意味着作为初始化过程的一部分,ApplicationContext实例会创建并配置所有的singleton bean。通常情况下这是件好事,因为这样在配置中的任何错误就会即刻被发现(否则的话可能要花几个小时甚至几天)。
Spring中的资源控制 Java标准的java.net.URL可以处理各种URL资源,但还是不够用来处理低级资源。例如:没有标准的URL实现用来访问相对类路径或者ServletContext有关的资源。而且缺少合意的功能,比如判断资源是否存在的方法。
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载