Spring循环事务commit问题

Spring循环事务commit问题

1.抛出问题

在工作中,遇到了一个需求,写一个批量任务,将商品表的一条记录给他赋上多个不同的活动号转移到另外一张活动表里,用以支持不同的活动,其他的不变,我的想法是写一个循环获取活动号数量--->批量任务先删除--->插入--->更新,但是在写好mapper后,在manager层里写事务时,调试发现每次事务只提交了一次,最后是怎么样的一个情况呢,就是insert完了,在执行更新,导致了更新完后,只有一个活动号,这可与我们的需求不符合啊,怎么办呢,我打开了debug,一步步调试,发现明明执行了插入的sql语句,但是打开数据库表更新就是没有数据产生,直到for循环执行完了才能更新到数据库,但这是不可能完成需求的,我原本的想法是执行一次循环--->删除重复数据---->插入数据---->更新数据----->for---->删除数据---****,但是现在直接变成了for--->删除--->插入--->更新,就没了。

2.上网查找问题关键

发现是只定义一个对象,所以for循环到最后只会commit一次事务,具体是怎么样的呢,下面是一个例子:

大概是下面这种情况:

 //更新
    @DefaultTransaction
    public void update(updateInAO in){
        ***Mapper.update(in);
    }
    
    
    //删除
    @DefaultTransaction
    public void delete(deleteInAO in){
        ***Mapper.delete(in);
    }
    
    //插入
    @DefaultTransaction
    public void insert(insertInAO in){
        ***Mapper.insert(in);
    }
    //更新数据库操作
    public update***(){
        String[] **id = get**List();
        deleteInAO deleteInAO = new deleteInAO();
        insertInAO insertInAO = new insertInAO();
        updateInAO updateInAO = new updateInAO();
        for(int i=0;i<**id.length;i++){
            //先删除
            deleteInAO.set**();
            deleteInAO.set**();
            delete(deleteInAO);
            //插入
            insertInAO.set**();
            insert(insertInAO);
            //更新
            updateInAO.set**();
            update(updateInAO);
        }
    }
    
    //将一个字符串以逗号分割,获取一个字符串列表
    public String[] get***List(){
        String[] **id = String***.split(",");
        return; **id;
    }

刚开始,我们大致是这么写的,由于

  deleteInAO deleteInAO = new deleteInAO();
        insertInAO insertInAO = new insertInAO();
        updateInAO updateInAO = new updateInAO();

这里每个对象都只初始化了一次,所以最后事务提交也只会把最后一次的数据commit到事务。

所以我们为了执行一次commit一次,达到我们所需要的需求,接下来进行代码改动。

   //更新
    @DefaultTransaction
    public void update(updateInAO in){
        ***Mapper.update(in);
    }


    //删除
    @DefaultTransaction
    public void delete(deleteInAO in){
        ***Mapper.delete(in);
    }

    //插入
    @DefaultTransaction
    public void insert(insertInAO in){
        ***Mapper.insert(in);
    }
    //更新数据库操作
    public update***(){
        String[] **id = get**List();
        deleteInAO deleteInAO = null;
        insertInAO insertInAO = null;
        updateInAO updateInAO = null;
        try {
            for(int i=0;i<**id.length;i++){
                //先删除
                deleteInAO = new deleteInAO();
                deleteInAO.set**();
                deleteInAO.set**();
                delete(deleteInAO);
                //插入
                insertInAO = new insertInAO();
                insertInAO.set**();
                insert(insertInAO);
                //更新
                updateInAO = new updateInAO();
                updateInAO.set**();
                update(updateInAO);
            }
        }catch(Exception e){
            log.error("e={}",e);
        }

    }

    //将一个字符串以逗号分割,获取一个字符串列表
    public String[] get***List(){
        String[] **id = String***.split(",");
        return; **id;
    }

在这段代码里,我们执行了**id.length次初始化,所以事务会提交 * *id.length次,具体是在:

  deleteInAO deleteInAO = null;
        insertInAO insertInAO = null;
        updateInAO updateInAO = null;
        try {
            for(int i=0;i<**id.length;i++){
                //先删除
                deleteInAO = new deleteInAO();
                deleteInAO.set**();
                deleteInAO.set**();
                delete(deleteInAO);
                //插入
                insertInAO = new insertInAO();
                insertInAO.set**();
                insert(insertInAO);
                //更新
                updateInAO = new updateInAO();
                updateInAO.set**();
                update(updateInAO);
            }

在这里初始化了多次对象,所以可以提交多次事务。

3.更多与此有关的问题

sql执行了但是数据库数据没发生改变:

没commit表示数据已经修改了,产生了redo和相应的undo,但是还没有真正生效,别的用户还是看不到你所做的更改。

4.事务的概念

   事务就是某一组操作,要么都执行,要么都不执行。

   比如你要去银行给朋友转钱,必然存在着从你的账户里扣除一定的金额和向你朋友账户里增加相等的金额这两个操作,这两个操作是不可分割的,无论是哪一个操作的失败,成功的操作也要恢复至最初的状态才能使银行和用户双方都满意,而这样的行为就牵扯到了事务的回滚。

5.事务的特性:

   原子性:一个事务是不可分割的最小单位。
   一致性:一个事务在执行之前和执行之后都必须处于一致性状态(比如说转账,前后两个账户的总金额是不会改变的)。
   隔离性:多个并发事务之间的操作不会互相干扰。
   持久性:提交的事务会使得修改的数据是永久的。

6.事务的回滚

   回滚:假设A给B转账,A的money--,B的money++,两者是一个整体。只有两个操作都成功完成了,事务才会提交,否则都会回滚到原来的状态。

   在emp表里再添加一个salary属性,把员工编号为1的员工的工资更改为1000,并且判断员工编号为3的员工的工资是否大于5000,如果小于5000则加1000,这两个操作为一个事务,要想事务能够正常的提交的条件是员工编号为3的员工的工资小于5000,工资加了1000,此时员工编号为1的员工的工资更改为1000.如果员工编号为3的员工的工资大于5000则中断程序,抛出异常,即操作2没有顺利完成,事务不应提交,而应该回滚到最初的状态。

   当然,不是所有的时候都需要恢复最初的状态的,所以有时候就会用到自己设置回滚点,上述程序中注释的部分就是自己添加了如果事务没有正常提交想要恢复到程序执行到哪个位置的回滚点。

7.总结

如果spring循环事务处理只需要一次cmomit的,只需要初始化一次对象就行了,如果需要多次commit事务的,就需要多次初始化对象。

8.致谢

感谢您的阅读,对于错误的地方,请在评论区指出来,博主好进行更正,谢谢!
更多详情请访问:juntech

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容