doncha
doncha
2019-08-16 16:01
采纳率: 41.7%
浏览 818
已采纳

spring boot加mybatis编程式事务在线程中回滚事务时,每隔一段时间就会提交事务

在Service层的线程方法,为了保证数据添加的正确所以加了锁。
线程里面有两个方法,为了保证添加时候数据正确,所以如果有方法出现错误就会实现事务回滚。

public String ticket(Integer sdid) {
        if (sd_id != null) {
            this.stock = schedulingService.findStock(sdid);
        }
        if (this.stock > 0) {
            TicketInspectRecord ticketInspectRecord = new TicketInspectRecord();
            ticketInspectRecord.setTir_tcr_id(1);
            ticketInspectRecord.setTir_tp_id(1);
            ticketInspectRecord.setTir_u_id(1);
            ticketInspectRecord.setTir_date(new Date());
            Thread thread = new Thread() {
                @Override
                public void run() {
                    synchronized (obj) {
                        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                        TransactionStatus status = transactionManager.getTransaction(def);
                        try {
                                                                ticketInspectRecordDao.inTicket(ticketInspectRecord);                                     
                                                                ticketInspectRecordDao.uStock(sd_id);//这一句必报错误
                            msg = "true";
                            transactionManager.commit(status);
                        } catch (Exception e) {
                            e.printStackTrace();
                            transactionManager.rollback(status);
                            msg = "false";
                        }
                    }
                }
            };
            thread.start();
            try {
                thread.join();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        return msg;
    }

奇怪的是在执行回滚的时候,有时候即便回滚了,方法ticketInspectRecordDao.inTicket(ticketInspectRecord)依旧会向数据库里插入数据,但是这种情况不是一直都会,项目重启的时候或者隔一段时间重新运行一次,就会出现这种情况。
研究了很久了,一直搞不明白问题在哪里

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • wojiushiwo945you
    毕小宝 2019-08-16 16:13
    已采纳

    问题可能出在 synchronized(obj) 上,这个 obj 是否是全局的一个公共对象呢?把它换成一个 xxx.class 类型试试呢。
    如果这个 obj 对不同线程来说是不同实例,本质上这里就没办法对其中的代码块做到同步约束了,因为锁不同。
    线程同步块应该受同一个锁保护。

    点赞 评论

相关推荐