spring 多线程事务的问题

线程不属于spring托管,故线程不能够默认使用spring的事务,也不能获取spring注入的bean

在被spring声明式事务管理的方法内开启多线程,多线程内的方法不被事务控制。

如下代码,线程内调用insert方法,spring不会把insert方法加入事务

就算在insert方法上加入@Transactional注解,也不起作用。

(?不解,试过将serviceA变成多例,也不行)

Java代码 

    @Service  
    public class ServiceA {  
       
        @Transactional  
        public void threadMethod(){  
            this.insert();  
             System.out.println("main insert is over");  
            for(int a=0 ;a<3;a++){  
                ThreadOperation threadOperation= new ThreadOperation();  
                Thread innerThread = new Thread(threadOperation);  
                innerThread.start();  
            }  
        }  
       
        public  class ThreadOperation implements Runnable {  
            public ThreadOperation(){  
            }  
            @Override  
            public void run(){  
                insert();  
                System.out.println("thread insert is over");  
            }  
        }  
       
        public void insert(){  
       
        //do insert......  
       
        }  
    }  

如果吧上面insert方法提出到新的类中,加入事务注解,就能成功的把insert方法加入到事务管理当中

Java代码

    @Service  
    public class ServiceA {  
       
    @Autowired  
    private ServiceB serviceB;  
       
        @Transactional  
        public void threadMethod(){  
            this.insert();  
            System.out.println("main insert is over");  
            for(int a=0 ;a<3;a++){  
                ThreadOperation threadOperation= new ThreadOperation();  
                Thread innerThread = new Thread(threadOperation);  
                innerThread.start();  
            }  
        }  
       
        public  class ThreadOperation implements Runnable {  
            public ThreadOperation(){  
            }  
            @Override  
            public void run(){  
                serviceB.insert();  
                System.out.println("thread insert is over");  
            }  
        }  
       
        public void insert(){  
       
            //do insert......  
       
        }  
    }  
       
    @Service  
    public class ServiceB {  
       
        @Transactional  
        public void insert(){  
       
            //do insert......  
       
        }  
       
    }  

另外,使用多线程事务的情况下,进行回滚,比较麻烦。

thread的run方法,有个特别之处,它不会抛出异常,但异常会导致线程终止运行。

最麻烦的是,在线程中抛出的异常即使在主线程中使用try...catch也无法截获

这非常糟糕,我们必须要“感知”到异常的发生。比如某个线程在处理重要的事务,当thread异常终止,我必须要收到异常的报告,才能回滚事务。

这时可以使用线程的UncaughtExceptionHandler进行异常处理,UncaughtExceptionHandler名字意味着处理未捕获的异常。更明确的说,它处理未捕获的运行时异常

如下代码

线程出要使用

①处要抛出异常

②处要捕捉异常,并且要抛出RuntimeException

③处手动处理回滚逻辑

Java代码

public class ServiceA {  
   
@Autowired  
private ServiceB serviceB;  
   
    @Transactional  
    public void threadMethod(){  
        this.insert();  
        System.out.println("main insert is over");  
        for(int a=0 ;a<3;a++){  
            ThreadOperation threadOperation= new ThreadOperation();  
            Thread innerThread = new Thread(threadOperation);  
            innerThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {  
               public void uncaughtException(Thread t, Throwable e) {  
                   try {  
                        serviceB.delete();③  
                   } catch (Exception e1) {  
                       e1.printStackTrace();  
                   }  
               }  
            });  
            innerThread.start();  
        }  
    }  
   
    public  class ThreadOperation implements Runnable {  
        public ThreadOperation(){  
        }  
        @Override  
        public void run(){  
            try {  
               serviceB.insert();  
           }catch (Exception ex){ ②  
            System.out.println(" Exception in run ");  
               throw new RuntimeException();  
           }  
            System.out.println("thread insert is over");  
        }  
    }  
   
    public void insert(){  
   
        //do insert......  
   
    }  
}  
   
@Service  
public class ServiceB {  
   
    @Transactional  
    public void insert() throws Exception{ ①  
   
    //do insert......  
   
    }  
   
    @Transactional  
    public void delete() throws Exception{   
   
        //do delete......  
   
    }  
   
}  

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

越来越没意思

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值