DataSourceTransactionManager进行事务管理

Stella981
• 阅读 561

  最近在做报表excel导入插入数据的时候,插入数据之前要清除当前用户和报告期下的数据,删除后执行错误导致删除运行,接口报错,

redis中获取的数据没有刷新,导致再次执行其他操作时报错。

  在这里用到DataSourceTransactionManager进行事务管理,可能需要多条sql完成对数据库的操作,比如账户登录,需要匹配用户名和密码,然后要增加积分,还要记录登录的ip和时间,这可能需要三个sql语句,这三个语句应当是一个整体,任意一个sql执行不成功,都表示这个业务没有执行完成,对前面的sql执行进行回滚。

  事务是数据库中的概念,就是对数据库的一组操作,由一条或多条sql组成。

  事务具有同步的特点,一条sql执行失败,其他sql都不会执行,即要么都执行,要么都不执行

xml配置:

<!-- 定义事务 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource" ref="dataSource"/></bean>

<!-- 配置 Annotation 驱动,扫描@Transactional注解的类定义事务  --><tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

<bean id="dataSource" class="net.bull.javamelody.SpringDataSourceFactoryBean">    <property name="targetName" value="kdataDataSource" /></bean>

public class KdataTxUtil {

    public static DataSourceTransactionManager getTxManager(){
        DataSourceTransactionManager transactionManager = (DataSourceTransactionManager) SpringContextHolder
                .getBean("transactionManager");
        return transactionManager;
    }

    public static TransactionStatus newTransaction(){
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。
        TransactionStatus status = getTxManager().getTransaction(def); // 获得事务状态
        return status ;
    }

    public static void commit(TransactionStatus status) {
        if ( status != null) {
            getTxManager().commit(status);
        }
    }

    public static void rollback(TransactionStatus status) {
        if( status != null) {
            getTxManager().rollback(status);
        }
    }
}

封装controller(web层)调用service接口

public Map callTxService(HttpServletRequest request, HttpServletResponse response,Class<? extends KdataService> serviceClass) {
    long start = System.currentTimeMillis() ;

 request.setAttribute("_req_start_time",System.currentTimeMillis());
    KdataContext.init();

    IResult rsParamCheck = new Result();
    rsParamCheck.failed("begin param check...");

    IResult rs = new Result();
    rs.failed("begin process ...");
    rs.setRequestTraceId(KdataContext.getContextAsString(KdataContext.SYS_REQUEST_TRACE_ID));
    KdataContext.traceHttpServletRequest(request);
    Map params = RestParam.parse( request);
    KdataContext.traceSetReqParam(params);
    TransactionStatus ts = KdataTxUtil.newTransaction() ;//获取事物对象
    try {
        KdataService kdataService = SpringContextHolder.getBean(serviceClass);

        kdataService.doService(params,rs);

        KdataTxUtil.commit(ts);
    }catch(KdataRollbackException e) {
        KdataTxUtil.rollback(ts);

        StringBuffer sb = new StringBuffer( e.getMessage());
        e.printStackTrace();
        rs.setException(Exceptions.getStackTraceAsString(e));
        rs.failed( sb.toString());
    }catch(Exception e) {
        KdataTxUtil.rollback(ts);

        StringBuffer sb = new StringBuffer("请求处理异常:"+e.getMessage());
        e.printStackTrace();
        rs.setException(Exceptions.getStackTraceAsString(e));
        if( e instanceof NullPointerException) {
            rs.failed("空指针异常:"+Exceptions.getStackTraceAsString(e));
        } else {
            rs.failed( sb.toString());
        }

    }

        KdataContext.addRequestTraceLog(  rs);//添加日志

    long end = System.currentTimeMillis(); //System.nanoTime()
    rs.setTimeSpent( end-start);
    return RestResult.getRestResult(rs);
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
3年前
Django之Django模板
1、问:html页面从数据库中读出DateTimeField字段时,显示的时间格式和数据库中存放的格式不一致,比如数据库字段内容为2012082616:00:00,但是页面显示的却是Aug.26,2012,4p.m.答:为了页面和数据库中显示一致,需要在页面格式化时间,需要添加<td{{dayrecord.p\_time|date:
Wesley13 Wesley13
3年前
4cast
4castpackageloadcsv.KumarAwanish发布:2020122117:43:04.501348作者:KumarAwanish作者邮箱:awanish00@gmail.com首页:
Easter79 Easter79
3年前
Spring支持多数据源的@Transactional事务注解
1、配置事务注解驱动、每个数据源对应的事务管理器,并定义“限定符”<tx:annotationdriven/    <bean id"transactionManager1" class"org.springframework.jdbc.DataSourceTransactionManager"  ... 
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这