事务使用分析经验总结

来源:互联网 发布:服务器端口是多少 编辑:程序博客网 时间:2024/05/21 22:56

 

前段时间版本开发中,同事问我,为什么他的功能没有事务回滚,由于事务问题一直在项目中存在,今天抽空了解决了该问题,下面是分析结果
分析过程是这样的:
1.模拟当时没有事务回滚的代码写了个测试代码
   在xhttp层的user类中加了个testtran方法
   在facade层的user类中加了个facadetran方法和servicetran方法,facadetran方法调用servicetran方法
   在service层的user类中加了个testtran方法,里面有更新和插入操作
配置applicationcontext-datasource.xml文件,关键代码
 
在配置中对facadetran和servicetran方法都进行了拦截。
配置application-facade.xml文件,这个同以前的配置是一样的,主要是用于事务控制的
框中部分就是最基本的spring事务配置,这里就不说了
 
2.测试结果
1.去掉facade* 这个匹配项,则事务不启作用,虽然有service *的匹配项
2.加上facade* 这个匹配项,有事务
 
3.结果分析
这是有事务时的当前本地变量中存的connection连接对象
start=10437382(oracle.jdbc.driver.OracleConnection@1e9445c)    --facade 的facadetran打印的
start service=10437382(oracle.jdbc.driver.OracleConnection@1e9445c)  --facade 的servicetran打印的
updateTrance=10437382(oracle.jdbc.driver.OracleConnection@1e9445c)  --dao层打印的
addTrance=10437382(oracle.jdbc.driver.OracleConnection@1e9445c)   --dao层打印的
end service=10437382(oracle.jdbc.driver.OracleConnection@1e9445c)  --facade 的servicetran打印的
end=10437382(oracle.jdbc.driver.OracleConnection@1e9445c)   ----facade 的facadetran打印的
所有的connection对象是一样的,因此保证了事务
 
这是没有事务时的当前本地变量中存的connection连接对象
start=5067839(oracle.jdbc.driver.OracleConnection@d62eb9)   --facade 的facadetran打印的
start service=26067327(oracle.jdbc.driver.OracleConnection@19a7cb8)  --facade 的servicetran打印的
updateTrance=11042980(oracle.jdbc.driver.OracleConnection@959dae)  --dao层打印的
addTrance=31319257(oracle.jdbc.driver.OracleConnection@db6fd3)  --dao层打印的
end service=27130714(oracle.jdbc.driver.OracleConnection@e10f10)  --facade 的servicetran打印的
end=25340210(oracle.jdbc.driver.OracleConnection@1323b6c)  ----facade 的facadetran打印的
每个connection对象都不一样,因此没有了事务
 
4.结论:
如果需要事务,请在最外层调入facade层时的方法时做事务,如facadeTran,而后面过滤到的也是没用的。因此这个开发时一定要注意,如果还是没有事务,可以直接打印当前的
连接对象是不是正确的
 
5.spring事务是这样实现的?
理解这个也对我们找问题也是有帮助的,假设如果我们自已实现一个事务也是可以的,spring也只是借助数据库来回滚的。
a.得到一个连接conn
b.把事务改成手动conn.setAutoCommit(false)
c.数据库相关业务操作
d.提交conn.commit();
e.如果业务失败,则在异常中comm.rollback();
f.最后需要在finally关闭连接
因此如果几个业务需要同时提交时必须在一个连接的原因了,spring只不过在这个流程中穿了个外套而已,呵呵
 
6.spring的事务传播行为介绍
  • PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
  • PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。
  •  
    7.问题补充
    ......
    String[] arr = str.split(",");
            try
            {
                getSqlMapClient().startTransaction();
                getSqlMapClient().startBatch();
                for (int i = 0; i < 3; i++)
                {
                    String serid = arr[0];
                    String name = arr[1];
                    Map<String, String> map = new HashMap<String, String>();
                    map.put("serid", serid + new Random().nextInt(10000));
                    map.put("name", name);
                    System.out.println("addTrance="
                            + this.getDataSource().getConnection());
                    getSqlMapClient().insert("AppInfoFor139.add", map);
                }
                getSqlMapClient().executeBatch();
                getSqlMapClient().commitTransaction();
            }
            catch (SQLException e)
            {
                throw new SepException(ErrorCode.INSERT_EXCEPTION, true, e);
            }
    ....
     
    象这种批处理,如果在facade打开了事务,这里手动设置也是无效的,因此需要注意这种需要手动提交的,就不能在facade开启事务了
     
    8.开发建议
    开发上面需要做下规范
    1、不能在接口层进行for循环调用facade层的方法,特别是做了事务代理的方法。这样从facade层就获取了一个db的connection。大量的组装url for循环调用导致了业务向数据库发了大量的获取连接和释放连接的不需要的开销)
     
    2、facade层定义的方法如果涉及到数据库操作且需要进行事务处理,需要和spring的bin定义文件中的事务代理类的add*之类的正则表达式一致。
     
    以上如果有错误,请大牛们纠正,呵呵
    原创粉丝点击
    热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 如果在超市买到过期商品怎么办 华润万家买的豆干过期了吃了怎么办 华润万家购物卡过期了怎么办 杜鹃花水浇多了树叶都掉了怎么办 游客行程因天气原因无法进行怎么办 携程旅游途中提前结束行程怎么办 小区附近商家卖东西很吵怎么办? 小区门口卖东西的喇叭太吵怎么办 我老婆是二婚带的小孩怎么办户口 ck手表带了脱不下来怎么办 消毒柜开孔尺寸高度太高了怎么办 苏宁易购买的东西比专卖店贵怎么办 手机打字键盘上没有语音功能怎么办 网贷催收发语音侮辱人怎么办 康力无机房电梯到楼层不关门怎么办 档案工龄少算了工资领开了怎么办 别人骚扰我打电话报警人走了怎么办 因外借医保卡被香港保险拒保怎么办 医保和社保断了一个月怎么办 苹果8呼叫受限请勿越权使用怎么办 药物储存2~8度没冰箱怎么办 利仁分体电饼铛做饼熟的慢怎么办 闲鱼买的东西自提有问题怎么办 老板油烟机的表层的膜掉了怎么办 给老板打工老板跑路了怎么办 公司要业务员承担客户的欠款怎么办 从自己公司出去抢自己客户怎么办? 在苏宁买东西买贵了怎么办 苏宁购物小票不见了未提货怎么办 结痂的地方扣掉了颜色不一样怎么办 实体店买手机不给发票怎么办 小孩学英语字母怎么都记不住怎么办 聊客老是提示网络连接失败怎么办? 天猫购物漏发客服不理怎么办 京东二维码被骗怎么办联系客服号码 京东客服打电话来让自己退款怎么办 淘宝上买到的衣服是坏的怎么办 淘宝上买到的产品是坏的怎么办? 在淘宝买到东西是坏的怎么办 冰箱冷冻室门生锈变形关不严怎么办 诲信电冰箱电脑板坏了怎么办