有一个场景
在执行完一系列的数据库操作后,通过获取数据库的流水,来发送校验短信。但是这个数据是在之前一系列的数据库操作的,数据库操作有事务,必须得等方法执行完成后才可以提交。
我这边发送校验短信写在了事务操作里通过线程池开了一个线程来执行的,然后会有这样的情况,有些时候会发送校验短信线程先获取 cpu 执行,然后导致获取不到数据库的流水数据,线程创建运行后,如何可以等待事务的执行结束后再执行线程内的操作。
我目前的写法是,在线程里加了 Thread.sleep(1000),让线程进行睡眠,在 1000ms 内 事务的操作一般都已经执行结束,此时执行线程内的发送校验短信操作。
但我不知道我这个方法会不会有什么影响,有学过线程操作,但是第一次在实际开发环境中使用到,问问有什么更好的处理方法。
1
bitholic 2019-08-29 12:42:35 +08:00 via iPhone
如果用的是 spring,可以看下
|
2
bitholic 2019-08-29 12:42:49 +08:00 via iPhone
TransactionSynchronizationManager
|
3
geelaw 2019-08-29 12:46:01 +08:00 via iPhone
为什么不在事务结束后再启动另一个线程?
用(反复)延时的方法进行同步是最后大招,不到万不得已不能使用。 |
4
Fren 2019-08-29 12:59:39 +08:00
这类操作不是应该丢到 MQ,解耦的么。。
|
5
woscaizi 2019-08-29 13:05:47 +08:00 via iPhone 1
应该改成同步操作吧。
话说获取流水为何要开启事务?还有写的操作? |
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(); } } |
7
jiejiecool 2019-08-29 13:59:18 +08:00 1
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override public void afterCommit() { } }); |
11
GreatEscape 2019-08-29 14:31:49 +08:00
@TransactionEventListener 注解,添加事务监听处理。
|
12
Renco OP @jiejiecool 感谢!此操作可行
|
13
Raymon111111 2019-08-29 14:34:42 +08:00
这种正确的做法确实是 MQ 解耦
|
14
larry123 2019-08-29 16:59:54 +08:00
CountDownLatch 了解一下
|