精华内容
下载资源
问答
  • springboot多线程事务
    2022-03-04 10:33:25
    @Slf4j
    @RequiredArgsConstructor
    public class MultiThreadTransaction {
    
        private final PlatformTransactionManager transactionManager;
    
        private void asyncSaveBatch() {
            // 线程个数
            final int SIZE = 6;
            // 交给单个线程处理,失败则加1
            final AtomicInteger failedCounter = new AtomicInteger();
    
            final CountDownLatch latch = new CountDownLatch(SIZE);
    
            final ExecutorService pool = Executors.newFixedThreadPool(SIZE);
    
            List<TransactionStatus> transactionStatuses = Collections.synchronizedList(new ArrayList<TransactionStatus>());
    
            long beginTime = System.currentTimeMillis();
    
            for (int i = 0; i < SIZE; i++) {
                pool.execute(() -> {
                    final boolean success = Math.random() > 0.1;
                    log.info(Thread.currentThread().getName() + ", success = " + success);
                    // 将每个线程中的事务状态存入集合单当中
                    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                    // 事物隔离级别,开启新事务,这样会比较安全些。
                    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
                    // 获得事务状态
                    TransactionStatus status = transactionManager.getTransaction(def);
                    transactionStatuses.add(status);
    
                    try {
                        /* 插入数据 */
                    } catch (Exception e) {
                        failedCounter.getAndIncrement();
                    } finally {
                        transactionManager.commit(status);
                    }
                    latch.countDown();
                });
            }
    
            try {
                latch.await();
                if (failedCounter.get() > 0) {
                    for (TransactionStatus transactionStatus : transactionStatuses) {
                        transactionStatus.setRollbackOnly();
                    }
                    log.info("执行了回滚过程,回滚事物数据集合大小" + transactionStatuses.size());
                }
                long endTime = System.currentTimeMillis();
                log.info("执行批量插入数据耗时" + (int) ((endTime - beginTime)) / 1000 + "秒");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    
    更多相关内容
  • // 如果其他线程已经报错 就停止线程 35 } 36 // 设置一个事务 37 DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 38 def.setPropagationBehavior(TransactionDefinition.PROPAGATION_...

    https://www.cnblogs.com/a5513633/p/13969222.html

    /**
      2  * 带回滚的异步任务回调
      3  * 基类
      4  * @author Administrator
      5  *
      6  */
      7 public abstract class BaseCallBack implements Callable<String> {
      8 
      9     private static Logger logger = LoggerFactory.getLogger(BaseCallBack.class);
     10     /**
     11      * 需要回滚计数器
     12      */
     13     protected CountDownLatch rollBackLatch;
     14     /**
     15      * 主线程等待计数器
     16      */
     17     protected CountDownLatch mainThreadLatch;
     18     /**
     19      * 是否需要回滚
     20      */
     21     protected AtomicBoolean rollbackFlag;
     22     /**
     23      * 事务
     24      */
     25     protected PlatformTransactionManager transactionManager;
     26 
     27     protected abstract void doWork();
     28 
     29     @Override
     30     public String call() throws Exception {
     31         if (rollbackFlag.get()) {
     32             logger.info("需要回滚,直接不用执行了");
     33             mainThreadLatch.countDown();
     34             return Constant.ERROR_STR; // 如果其他线程已经报错 就停止线程
     35         }
     36         // 设置一个事务
     37         DefaultTransactionDefinition def = new DefaultTransactionDefinition();
     38         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。
     39         TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
     40         try {
     41             logger.info("业务开始处理:{}", this.getClass().getName());
     42             this.doWork();
     43             logger.info("业务处理结束:{}", this.getClass().getName());
     44             // 业务处理结束
     45             mainThreadLatch.countDown();
     46             logger.info("线程内正常 mainThreadLatch.countDown();");
     47             rollBackLatch.await();// 线程等待
     48             if (rollbackFlag.get()) {
     49                 logger.info("回滚事务:{}", this.getClass().getName());
     50                 transactionManager.rollback(status);
     51             } else {
     52                 logger.info("提交事务:{}", this.getClass().getName());
     53                 transactionManager.commit(status);
     54             }
     55             return Constant.SAVE_SUCCESS;
     56         } catch (Exception e) {
     57             e.printStackTrace();
     58             // 如果出错了 就放开锁 让别的线程进入提交/回滚 本线程进行回滚
     59             rollbackFlag.set(true);
     60             transactionManager.rollback(status);
     61             rollBackLatch.countDown();
     62             mainThreadLatch.countDown();
     63             logger.info("线程内异常 mainThreadLatch.countDown();");
     64             return "操作失败:" + e.getMessage();
     65         }
     66     }
     67 
     68     public CountDownLatch getRollBackLatch() {
     69         return rollBackLatch;
     70     }
     71 
     72     public void setRollBackLatch(CountDownLatch rollBackLatch) {
     73         this.rollBackLatch = rollBackLatch;
     74     }
     75 
     76     public CountDownLatch getMainThreadLatch() {
     77         return mainThreadLatch;
     78     }
     79 
     80     public void setMainThreadLatch(CountDownLatch mainThreadLatch) {
     81         this.mainThreadLatch = mainThreadLatch;
     82     }
     83 
     84     public AtomicBoolean getRollbackFlag() {
     85         return rollbackFlag;
     86     }
     87 
     88     public void setRollbackFlag(AtomicBoolean rollbackFlag) {
     89         this.rollbackFlag = rollbackFlag;
     90     }
     91 
     92     public PlatformTransactionManager getTransactionManager() {
     93         return transactionManager;
     94     }
     95 
     96     public void setTransactionManager(PlatformTransactionManager transactionManager) {
     97         this.transactionManager = transactionManager;
     98     }
     99 
    100 }
    复制代码
    
    展开全文
  • spring boot 纯注解方法事务控制回滚,注解+简单配置文件使用多线程demo
  • 主要介绍了SpringBoot事务使用及回滚实现代码详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • SpringBoot 多线程事务处理

    千次阅读 2021-01-22 14:49:22
    Springboot多线程下,处理事务; 目前很多开发的小伙伴们,都开始采用Springboot了,因为给我们带来了许多的开发便利,只需要我们关注编写逻辑代码。在工作中是会有很多小伙伴在项目逐步实用到多线程、线程池等...

    Springboot 在多线程下,处理事务;

       目前很多开发的小伙伴们,都开始采用Springboot了,因为给我们带来了许多的开发便利,只需要我们关注编写逻辑代码。在工作中是会有很多小伙伴在项目逐步实用到多线程、线程池等相关技术,但是在使用多线程会出各种各样的问题;事务就是其中一种相对麻烦的事情;
    
    大家都知道Springboot  只需要使用注解标签@Transactional 就可以使用事务了;但是往往在多线程下该处理事务的办法就失效,毫无效果;那又该如何呢?
    首先大家都知道控制事务有两种方式;第一种就是刚才所说的注解式事务、第二种就是编程式事务;既然第一种失效那么我们就使用第二种方式来实现嘛;废话不多说,上代码!
    
    package com.slsp.cloud.config;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.slsp.cloud.bean.User;
    import com.slsp.cloud.service.UserService;
    import lombok.SneakyThrows;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang.math.RandomUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.stereotype.Component;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.transaction.support.TransactionCallback;
    import org.springframework.transaction.support.TransactionTemplate;
    
    import javax.annotation.Resource;
    import java.math.BigDecimal;
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.UUID;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 项目初始化加载
     */
    @Component
    @Slf4j
    public class TradeApplicationRunner implements ApplicationRunner
    {
    
    
        @Autowired
        private TransactionTemplate transactionTemplate;
    
        @Autowired
        private UserService userService;
    
        /**
         * 模拟多线程下事务处理
         * @param args
         * @throws Exception
         */
        @Override
        public void run(ApplicationArguments args) throws Exception
        {
            //线程池
            ExecutorService cachedThreadPool = Executors.newFixedThreadPool(5);
            for(int i=0;i<1;i++)
            {
                cachedThreadPool.execute(new Runnable()
                {
                    @SneakyThrows
                    public void run()
                    {
                        log.info("多线程执行;");
                        //开启编程式事务;
                        transactionTemplate.execute(new TransactionCallback<Boolean>()
                        {
                            @Override
                            public Boolean doInTransaction(TransactionStatus transactionStatus)
                            {
                                try
                                {
    
                                    User usr = new User();
                                    //随机名字
                                    String name = UUID.randomUUID().toString().replace("-", "");
                                    System.out.println(name);
                                    usr.setUserName(name);
                                    usr.setSex(1);
                                    //插入数据库
                                    userService.save(usr);
    
                                    //模拟报错;
                                    int i=10/0;
    
                                    String name2 = UUID.randomUUID().toString().replace("-", "");
                                    System.out.println(name2);
                                    User usr2 = new User();
                                    usr2.setUserName(name2);
                                    usr2.setSex(1);
                                    userService.save(usr2);
    
                                    return true;
                                }
                                catch (Exception e)
                                {
                                    //事务回滚;
                                    transactionStatus.setRollbackOnly();
                                    e.printStackTrace();
                                    return false;
                                }
                            }
    
                        });
    
                    }
                });
            }
        }
    }
    
    

    打完收工;简单方便;

    展开全文
  • 主要介绍了Spring-Boot中如何使用多线程处理任务方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • springboot控制多线程事务

    千次阅读 2021-05-18 15:10:06
    import org.springframework.stereotype.Service; import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; import java.util.... } } 注意该种方式未经过太测试
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.support.TransactionTemplate;
    
    import javax.annotation.Resource;
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.atomic.AtomicBoolean;
    
    @Service
    public class ThreadTest {
        @Resource
        private TransactionTemplate transactionTemplate;
    
        @Resource
        private TestMapper testMapper;
    
    
        public void test1() {
            final CountDownLatch al = new CountDownLatch(3);
            final AtomicBoolean ab = new AtomicBoolean(false);
    
            CompletableFuture.runAsync(() -> {
                transactionTemplate.execute((var e) -> {
                    try {
                        TestDto testDto = new TestDto();
                        testDto.setName("测试线程1");
                        testMapper.add(testDto);
                        al.countDown();
                        al.await();
                        if (ab.get()) throw new RuntimeException("手动抛错");
                    } catch (Exception exception) {
                        //事务回滚;
                        e.setRollbackOnly();
                        exception.printStackTrace();
                        al.countDown();
                        ab.set(true);
                        return false;
                    }
    
                    return true;
                });
            });
            CompletableFuture.runAsync(() -> {
                transactionTemplate.execute((var e) -> {
                    try {
                        TestDto testDto = new TestDto();
                        testDto.setName("测试线程2");
                        testMapper.add(testDto);
    
                        al.countDown();
                        al.await();
                        if (ab.get()) throw new RuntimeException("手动抛错");
                    } catch (Exception exception) {
                        //事务回滚;
                        e.setRollbackOnly();
                        exception.printStackTrace();
                        al.countDown();
                        ab.set(true);
                        return false;
                    }
    
                    return true;
    
                });
            });
            transactionTemplate.execute((var e) -> {
                try {
                    TestDto testDto = new TestDto();
                    testDto.setName("测试主线程");
                    testMapper.add(testDto);
                    
                    al.countDown();
                    al.await();
                    if (ab.get()) throw new RuntimeException("手动抛错");
                } catch (Exception exception) {
                    //事务回滚;
                    e.setRollbackOnly();
                    exception.printStackTrace();
                    al.countDown();
                    ab.set(true);
                    return false;
                }
    
                return true;
            });
        }
    }
    
    

    注意该种方式未经过太多测试

    展开全文
  • 本篇文章主要介绍了详解Spring-Boot中如何使用多线程处理任务,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
  • SpringBoot多线程事务回滚

    千次阅读 2021-03-16 16:42:31
    12 //主线程业务执行完毕 如果其他线程也执行完毕 且没有报异常 正在阻塞状态中 唤醒其他线程 提交所有的事务13 //如果其他线程或者主线程报错 则不会进入if 会触发回滚 14 if (!rollbackFlag.get()) {15 try{16 ...
  • springboot Async 多线程事务失效

    千次阅读 2020-01-03 17:48:44
    异步方法和事务处理方法不能写在一个service类里
  • 前言 随着业务的不断深入,总有一些接口需要操作数据库中的很表,前阵子公司的一个...一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或线程一直等待。 用给定的计数 初始化 CountDownL.
  • 多线程-springboot实现多线程处理任务

    千次阅读 2021-01-06 11:16:30
    2.springboot实现多线程 1.在入口类上开启多线程 @SpringBootApplication //@EnableScheduling @EnableAsync public class SampleController { public static void main(String[] args) throws Exception { ...
  • 实现系统对数据源的操作。 实现系统对数据源的分布式事务管理,包括事务的提交和回滚。
  • SpringBoot使用多线程处理任务

    千次阅读 2022-03-18 14:11:24
    SpringBoot使用多线程处理任务
  • SpringBoot多线程一个事务

    千次阅读 2020-04-29 12:08:22
    最近工作中遇到了一个问题 由于某个批量功能执行时间实在太慢 于是想着使用多线程的方法加速 但是运行了之后发现 他们不存在于一个事务中,想要一个报错 全体回滚暂时不明白该怎么实现 相关伪代码 @Transactional ...
  • springboot+多线程

    千次阅读 2020-06-22 15:12:07
    springboot的过程中,我们会使用到多线程去同时执行某个任务,那么我们就需要多线程,在以前的java中是自己去实现Thread或者runnable来实现多线程springboot中已经自己拥有了多线程的注解@Async,那么我们现在...
  • SpringBoot事务失效

    2021-08-30 16:40:57
    @Transactional 应用在非 public 修饰...TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 TransactionDefinition.PROPAGATION_NOT_SUPPO.
  • SpringBoot执行多线程

    2021-09-28 10:52:44
    1.新建配置类,配置线程池 @Configuration @EnableAsync public class ThreadPoolConfiguration { @Bean("ThreadPools") public Executor doSomethingExecutor() {... // 核心线程数,线程池创建时候初始化的线程
  • 一、springBoot集成多线程 1.1 快速集成方法一 -------------------------方法一:创建AsyncConfig类并实现AsyncConfigurer类,重写方法------------------------------ import org.springframework.aop....
  • SpringBoot事务失效场景

    2022-01-02 20:44:12
    如果我们在开发过程中,把有事务的方法定义了错误的权限,就会导致事务功能出错。众所周知,spring要求被代理的方法必须是public的。说白了,在AbstrctFallbackTransactionAttributedSource类的...
  • 主要介绍了springboot手动事务回滚的实现方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
  • 事务Springboot处理事务@Transactional
  • 目录 ...@SpringBootTest @RunWith(SpringRunner.class) public class PlantTest { @Autowired private PlantService plantService; @Autowired private TransactionThreadPoolExecutor execut
  • springboot项目中多线程应用,异步处理,异步调用 多线程的应用 线程池的应用 异步处理 异步调用 随着开发经验的积累,我们逐渐都了解到了项目中需要多线程的应用或者线程池的应用,有一些耗时的业务需要我们去进行...
  • spring 多线程事务的问题

    万次阅读 2017-08-09 16:53:41
    在被spring声明式事务管理的方法内开启多线程多线程内的方法不被事务控制。   如下代码,线程内调用insert方法,spring不会把insert方法加入事务 就算在insert方法上加入@Transactional注解,也不起作用。 J
  • 主要介绍了SpringBoot 任务并行+线程池处理的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 之前有文章提供了springboot多数据源动态注册切换的整合方案,在后续使用过程中,发现在事务控制中有多种bug发生,决定对此问题进行分析与解决 前情提要 多数据源切换流程结构图如下所示,包含几个组成元素 自定义...
  • 事务在编程中分为两种:声明式事务处理和编程式事务处理 **编程式事务处理:**编码方式实现事务管理,常与模版类TransactionTemplate(推荐使用) 在业务代码中实现事务。 可知编程式事务每次实现都要单独实现,但...
  • 事务一致性一定要你的数据库引擎支持,我用的数据库是mysql,常见两种搜索引擎,MyISAM和InnoDb,关于它们的区别,网上很多人罗列了,我这里最重要的就是InnoDb支持事务,MyISAM不支持事务。在mysql里面,可以单独为每...
  • ????推荐大家关注一个公众号????...每日英文You never know how strong you really are until being strong is the only ...不到没有退路之时,你永远不会知道自己有强大。每日掏心话人在不同的阶段,会有不同的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,034
精华内容 9,213
关键字:

springboot多线程事务

spring 订阅