zoukankan      html  css  js  c++  java
  • Springboot事务回滚(改良版)

    前段时间发过此类demo,后经大神改版,学到了一点,遂记录一下

     1     /**
     2      * 利用线程池起两个任务
     3      */
     4     public String thredSubmit(String uuidStr, List<VariationMapIn> mapIns, List<ApproveHis> hisList, String[] ids,
     5             Long guToJuPartyId) {
     6         SubmitToPer submitToPerTask = new SubmitToPer(uuidStr, hisList, mapIns,
     7                 JtCommonUtil.getUserView().getPartyId());
     8 
     9         XianSubmit xianianSubmitTask = new XianSubmit(JtCommonUtil.getUserView().getOrganization().getGroupCode(),
    10                 mapIns, JtCommonUtil.getUserView().getPartyId());
    11 
    12         String result = SynTaskUtils.doWork(Arrays.asList(submitToPerTask, xianianSubmitTask), transactionManager);
    13         return result;
    14     }
     1 /**
     2  * 第一个任务
     3  */
     4 public class SubmitToPer extends BaseCallBack {
     5 
     6     private String uuidStr;
     7     private List<ApproveHis> hisList;
     8     private List<VariationMapIn> mapIns;
     9     private Long partyId;
    10 
    11     public SubmitToPer(String uuidStr, List<ApproveHis> hisList, List<VariationMapIn> mapIns, Long partyId) {
    12         super();
    13         this.uuidStr = uuidStr;
    14         this.hisList = hisList;
    15         this.mapIns = mapIns;
    16         this.partyId = partyId;
    17     }
    18 
    19     @Override
    20     protected void doWork() {
    21         // 业务处理开始
    22         MapInDealService mapInDealService = (MapInDealService) ApplicationUtil.getBean("mapInDealService");
    23         mapInDealService.submitToPer(uuidStr, mapIns, hisList, partyId);
    24     }
    25 
    26 }
     1 /**
     2  * 第二个任务
     3  */
     4 public class XianSubmit extends BaseCallBack {
     5 
     6     private String groupCode;
     7     private List<VariationMapIn> mapIns;
     8     private Long partyId;
     9 
    10     public XianSubmit(String groupCode, List<VariationMapIn> mapIns, Long partyId) {
    11         super();
    12         this.groupCode = groupCode;
    13         this.mapIns = mapIns;
    14         this.partyId = partyId;
    15     }
    16 
    17     @Override
    18     protected void doWork() {
    19         SpanCheckService spanCheckService = (SpanCheckService) ApplicationUtil.getBean("spanCheckService");
    20         String str = spanCheckService.xianCheckIn(mapIns, partyId, groupCode);
    21         if (!Constant.SUCCESS_STR.equals(str))
    22             throw new RuntimeException(str);
    23     }
    24 
    25 }
      1 /**
      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 }
     1 /**
     2  * 异步线程执行器 携带回滚
     3  * 
     4  * @author Administrator
     5  *
     6  */
     7 public class SynTaskUtils {
     8 
     9     /**
    10      * 日志
    11      */
    12     private static Logger logger = LoggerFactory.getLogger(SynTaskUtils.class);
    13 
    14     public static String doWork(List<? extends BaseCallBack> tasks, PlatformTransactionManager transactionManager) {
    15         if (tasks == null || tasks.size() <= 0) {
    16             return Constant.SUCCESS_STR;
    17         }
    18         logger.info("开始执行一组线程..........................................................");
    19         CountDownLatch rollBackLatch = new CountDownLatch(1);
    20         CountDownLatch mainThreadLatch = new CountDownLatch(tasks.size());
    21         AtomicBoolean rollbackFlag = new AtomicBoolean(false);
    22         List<Future<String>> list = new ArrayList<Future<String>>();
    23         for (BaseCallBack task : tasks) {
    24             task.setMainThreadLatch(mainThreadLatch);
    25             task.setRollbackFlag(rollbackFlag);
    26             task.setRollBackLatch(rollBackLatch);
    27             task.setTransactionManager(transactionManager);
    28             logger.info("添加任务:{}", task.getClass().getName());
    29             Future<String> future = TestExecutorUtil.getInstance().getExecutor().submit(task);
    30             list.add(future);
    31         }
    32         // 主线程业务执行完毕 如果其他线程也执行完毕 且没有报异常 正在阻塞状态中 唤醒其他线程 提交所有的事务
    33         // 如果其他线程或者主线程报错 则不会进入if 会触发回滚
    34         try {
    35             logger.info("主线程开始等待。");
    36             mainThreadLatch.await();
    37             logger.info("主线程等待结束。");
    38             if (!rollbackFlag.get()) {
    39                 logger.info("不需要回滚。");
    40                 rollBackLatch.countDown();
    41                 return Constant.SUCCESS_STR;
    42             } else {
    43                 logger.info("需要回滚。");
    44                 for (Future<String> f : list) {
    45                     String result = f.get();
    46                     if (!Constant.SAVE_SUCCESS.equals(result)) {
    47                         logger.info("返回值:{}", result);
    48                         return result;
    49                     }
    50                 }
    51                 return Constant.SUCCESS_STR;
    52             }
    53         } catch (Exception e) {
    54             return "操作出现异常。";
    55         }finally {
    56             logger.info("结束执行一组线程..........................................................");
    57         }
    58     }
    59 
    60 }
     1 /**
     2  * 公用线程池
     3  * 
     4  * @author Administrator
     5  *
     6  */
     7 public class TestExecutorUtil {
     8 
     9     /**
    10      * 线程池
    11      */
    12     private ExecutorService executor = Executors.newFixedThreadPool(10);
    13 
    14     /**
    15      * 单利
    16      * 
    17      * @author Administrator
    18      *
    19      */
    20     private static class Instance {
    21         private static final TestExecutorUtil instance = new TestExecutorUtil();
    22     }
    23 
    24     private TestExecutorUtil() {
    25     }
    26 
    27     public static TestExecutorUtil getInstance() {
    28         return Instance.instance;
    29     }
    30 
    31     public TestExecutorService getExecutor() {
    32         return executor;
    33     }
    34 
    35 }
  • 相关阅读:
    linux-文件
    字符串函数
    函数
    内存管理
    静态库、动态库文件制作
    Makefile 待完善
    指针
    开发板GEC6816环境搭建,使用VS code
    C语言数组
    连接开发板下载程序
  • 原文地址:https://www.cnblogs.com/a5513633/p/13969222.html
Copyright © 2011-2022 走看看