V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Renco
V2EX  ›  Java

如何等一个事务结束后,在执行线程的内容。

  •  
  •   Renco · 2019-08-29 11:51:12 +08:00 · 3793 次点击
    这是一个创建于 1897 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一个场景

    在执行完一系列的数据库操作后,通过获取数据库的流水,来发送校验短信。但是这个数据是在之前一系列的数据库操作的,数据库操作有事务,必须得等方法执行完成后才可以提交。

    我这边发送校验短信写在了事务操作里通过线程池开了一个线程来执行的,然后会有这样的情况,有些时候会发送校验短信线程先获取 cpu 执行,然后导致获取不到数据库的流水数据,线程创建运行后,如何可以等待事务的执行结束后再执行线程内的操作。

    我目前的写法是,在线程里加了 Thread.sleep(1000),让线程进行睡眠,在 1000ms 内 事务的操作一般都已经执行结束,此时执行线程内的发送校验短信操作。

    但我不知道我这个方法会不会有什么影响,有学过线程操作,但是第一次在实际开发环境中使用到,问问有什么更好的处理方法。

    14 条回复    2019-08-29 16:59:54 +08:00
    bitholic
        1
    bitholic  
       2019-08-29 12:42:35 +08:00 via iPhone
    如果用的是 spring,可以看下
    bitholic
        2
    bitholic  
       2019-08-29 12:42:49 +08:00 via iPhone
    TransactionSynchronizationManager
    geelaw
        3
    geelaw  
       2019-08-29 12:46:01 +08:00 via iPhone
    为什么不在事务结束后再启动另一个线程?

    用(反复)延时的方法进行同步是最后大招,不到万不得已不能使用。
    Fren
        4
    Fren  
       2019-08-29 12:59:39 +08:00
    这类操作不是应该丢到 MQ,解耦的么。。
    woscaizi
        5
    woscaizi  
       2019-08-29 13:05:47 +08:00 via iPhone   ❤️ 1
    应该改成同步操作吧。
    话说获取流水为何要开启事务?还有写的操作?
    Lin0936
        6
    Lin0936  
       2019-08-29 13:10:59 +08:00
    正好之前有差不多的需求,于是抽了个共通,在需要等待的地方调 await()就完事。( JAVA 新人,写得不对的请大佬指摘)


    public class Task {

    private boolean completed = false;

    synchronized public void await() {
    while (!completed) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    synchronized private void complete() {
    completed = true;
    this.notifyAll();
    }

    public void async(Runnable runnable) {
    new Thread(() -> {
    runnable.run();
    complete();
    }).start();
    }
    }
    jiejiecool
        7
    jiejiecool  
       2019-08-29 13:59:18 +08:00   ❤️ 1
    TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
    @Override
    public void afterCommit() {

    }
    });
    sonice
        8
    sonice  
       2019-08-29 14:03:13 +08:00   ❤️ 1
    @Lin0936 synchronized 写在最前面看着好别扭。。。
    Renco
        9
    Renco  
    OP
       2019-08-29 14:16:06 +08:00
    @Fren 目前公司框架没有 MQ
    Renco
        10
    Renco  
    OP
       2019-08-29 14:16:38 +08:00
    @woscaizi 确实有事务操作应该同步,写代码写错了
    GreatEscape
        11
    GreatEscape  
       2019-08-29 14:31:49 +08:00
    @TransactionEventListener 注解,添加事务监听处理。
    Renco
        12
    Renco  
    OP
       2019-08-29 14:33:28 +08:00
    @jiejiecool 感谢!此操作可行
    Raymon111111
        13
    Raymon111111  
       2019-08-29 14:34:42 +08:00
    这种正确的做法确实是 MQ 解耦
    larry123
        14
    larry123  
       2019-08-29 16:59:54 +08:00
    CountDownLatch 了解一下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1023 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 22:08 · PVG 06:08 · LAX 14:08 · JFK 17:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.