`
solomon523
  • 浏览: 14928 次
社区版块
存档分类
最新评论

spring 多线程事务的问题

阅读更多

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

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

 

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

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

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

@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方法加入到事务管理当中

@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

③处手动处理回滚逻辑

@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.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......
 
    }
 
}

 

 

分享到:
评论
1 楼 Mind-Hacks 2016-11-02  
哥们我按照你的说法,终于成功了。我是在本类启动的多线程,然后调用本类的方法,也是没有事务,把run()方法里面的service移动出去就好了。
不过我找到原因了,哈哈哈,因为调用本类的方法,会让注解,还是AOP切面无法注切入(具体看事务管理实现源码)。调用别的类的话,然后就会有事务切入,然后就会有管理     

相关推荐

    spring boot注解事务+多线程

    在Spring Boot应用中,事务管理和多线程是两个非常关键的特性,特别是在处理复杂的业务逻辑时。本示例将深入探讨如何使用注解来实现事务控制以及如何在Spring Boot中运用多线程。 首先,让我们关注"注解事务"。在...

    spring 多线程队列执行

    Spring AOP(面向切面编程)可以与多线程结合,用于在任务执行前后添加日志记录、事务管理等逻辑。通过定义切面和通知,我们可以实现对多线程任务的统一管理和监控。 6. **线程安全**: 在多线程环境下,需要特别...

    springboot多数据源即分布式事务解决方案,添加对多线程的支持

    3. 业务逻辑层:使用`@Transactional`注解标记事务边界,可能还使用了`@Transactional(propagation = Propagation.REQUIRES_NEW)`来处理多线程事务。 4. 测试用例:包含了对多数据源和分布式事务功能的测试,验证...

    maven管理的Spring多线程任务demo

    本示例"maven管理的Spring多线程任务demo"着重展示了如何在Spring框架中利用Maven进行项目构建,并实现多线程任务处理。在SSM(Spring、SpringMVC、MyBatis)框架背景下,如果你已经有所了解,那么这个例子将帮助你...

    java中spring里实现多线程

    当我们谈到在Spring中实现多线程,实际上是在讨论如何在Spring环境中创建、管理和协调并发执行的任务。这涉及到Java的并发API以及Spring对这些API的包装和扩展。 首先,让我们了解Java中的多线程基础。在Java中,...

    Spring事务流程图

    Spring事务管理是Spring框架的核心特性之一,主要用于处理应用程序中的数据一致性问题。...通过理解和使用Spring事务流程图,我们可以更好地设计和优化我们的应用程序,确保在多线程环境下的数据一致性。

    spring-tx事务管理实例

    Spring事务管理是企业级Java应用中不可或缺的一部分,它确保了数据的一致性和完整性,尤其是在多线程和分布式环境中。本实例将深入探讨Spring事务管理的实现与应用。 首先,Spring事务管理分为编程式事务管理和声明...

    Spring事务处理-ThreadLocal的使用

    在实际应用中,理解ThreadLocal在Spring事务处理中的作用有助于优化并发性能和解决多线程环境下的事务问题。例如,如果线程之间需要共享数据,但又不想影响其他线程,ThreadLocal就是一个理想的选择。同时,也要注意...

    Spring配置JTA事务管理

    - JTA的并发问题:在多线程环境下,你需要理解如何避免死锁和其他并发问题。 最后,提到的`ibatis`文件可能是MyBatis的配置或者相关代码。MyBatis是一个优秀的持久层框架,它可以与Spring的JTA事务管理无缝集成。在...

    spring4+junit4.8 +多线程TheadTool

    在"spring4+junit4.8 +多线程TheadTool"的场景下,我们可以深入探讨以下几个知识点: 1. **Spring4框架**:Spring4在Spring3的基础上进行了许多改进,包括对Java 8的支持,提升了与NoSQL数据库的集成,以及对...

    java 后端学习资料包含(spring,多线程).zip

    此外,Spring框架还提供了`@Transactional`注解,用于声明式事务管理,这在多线程环境中尤为重要,因为正确地管理事务边界是确保数据一致性的关键。 本资料包中可能包含有关Spring框架的源码解析,帮助开发者理解其...

    spring 事务传播与隔离级别DEMO

    总的来说,Spring的事务管理提供了一套灵活且强大的机制,帮助我们在多线程和分布式环境中保证数据一致性。通过学习和实践这个DEMO,开发者可以深化对事务处理的理解,从而提高系统的稳定性和可靠性。

    SpringBoot事务和Spring事务详讲

    - **并发控制**:在多线程环境下,需要注意事务之间的隔离级别设置,以避免死锁或其他并发问题。 - **性能考量**:过度使用事务可能会对性能产生负面影响,因此需要合理设计事务范围。 #### 七、总结 事务管理是...

    spring事务,xml方式和注解方式

    在多线程、分布式系统中,事务管理显得尤为重要。本节将详细介绍Spring如何通过XML配置和注解方式来实现事务管理。 首先,我们来看Spring事务的XML配置方式。在Spring中,事务管理通常通过`&lt;tx:annotation-driven&gt;`...

    全面分析_Spring_的编程式事务管理及声明式事务管理

    Spring 框架的事务管理是其核心特性之一,它为开发者提供了强大的支持,确保了在多线程和并发环境中数据的一致性和完整性。本教程将深入探讨 Spring 的编程式事务管理和声明式事务管理,帮助你理解这两种方式的差异...

    Spring多数据源分布式事务管理

    总的来说,Spring多数据源分布式事务管理是一项复杂的任务,涉及到Spring的AOP、数据源路由、事务管理等多个方面。通过Atomikos这样的JTA实现,我们可以有效地解决分布式环境下的事务一致性问题。同时,结合Druid和...

    从ThreadLocal的使用到Spring的事务管理

    结合ThreadLocal和Spring事务管理,我们可以在多线程环境中实现高效且一致的业务处理。例如,Spring在处理每个HTTP请求时,会为每个请求分配一个单独的线程。我们可以通过ThreadLocal来保存请求相关的状态信息,而...

    多线程及spring相关面试专题及答案.zip

    6. **Spring事务管理**:Spring提供了声明式和编程式的事务管理,确保在多线程环境中数据的一致性。 7. **Spring Bean**:Spring容器管理的对象称为Bean,容器通过XML、注解或Java配置来定义Bean的生命周期和装配...

    springtransaction 事务管理

    虽然Spring提供了强大的事务管理功能,但在一些特定情况下,如静态方法、异步方法、多线程环境下的事务可能无法正常工作,需要开发者注意并进行特殊处理。 在实际项目中,`springtransaction`工程可能是包含了一个...

    java多线程处理数据库数据

    2. **事务管理**:在多线程环境中,可能需要考虑事务的一致性。可以使用Spring的`@Transactional`注解或者手动开启和提交事务。 3. **错误处理**:捕获并处理异常,避免单个任务失败导致整个线程池停止工作。 4. **...

Global site tag (gtag.js) - Google Analytics