比如我需要执行很多任务,执行任务比较耗时,所以才去了异步执行
我的调度方法把要执行的任务拿到(比如在方法 A 中)
然后通过异步方法去执行(方法 B 中)
我需要修改这个任务状态为执行中
这个时候,有个事务问题,就是,我修改任务状态是在 A 中,不能在 B 中,因为 B 有可能会执行很久才完成,才进行事
务提交,外部看着任务的状态会很长一段时间没有状态
所以,我在 A 中修改任务状态,然后异步执行 B
但是,如果 B 执行的足够快,有可能我的 A 还没有提交,B 查询得到的状态就是空的,这个时候,A 提交了,然后 B 提交
了,那么 B 提交的数据里,状态就是空的,把 A 提交的任务状态覆盖了
这个场景可能没那么恰当,但是应该能表达我想说的意思了
就是这种有异步执行的场景下,为了确保前一个事务确实提交了,再执行异步方法,只有手动提交事务么?有没有
更优雅的方法呢,谢谢~
1
t202201 2023-01-05 22:21:15 +08:00 via iPhone
没看明白,需要异步执行的到底是什么?
A 、B 和异步的任务,三者是什么关系? |
2
NoKey OP @t202201 实际意思就是,A 要写数据,B 要读写数据,A ,B 各在一个事务里面,如何确保 A 的事务先提交,然后 B 就能够读取到正确的数据。目前采取的是手动提交事务的方式,想知道有没更好的办法
|
4
Avn 2023-01-05 22:32:30 +08:00
既不在 A 的事务中进行、也不在 B 的事务中进行,而是在 B 前面再开个独立的小事务,把任务状态修改掉。
|
5
NoKey OP @Avn 我理解一下,是不是说,在 A 和 B 之间,新开一个事务,把事情给干了,这个事务返回的时候,就提交了,然后执行 B ?
|
6
Avn 2023-01-05 22:45:37 +08:00
@NoKey 对的。记录状态或日志的操作,不需要放在主事务里面。因为即使主事务发生异常事务回滚,大部分情况下记录状态或日志的操作也不需要、不能回滚,而是要被准确地记录下来,所以可以用独立的小事务来处理这些操作。
|
7
imv2er 2023-01-05 22:56:22 +08:00
countdownlatch 解忧愁。A 的事务提交完 就 countdown b 读代码开始运行
|
8
kwh 2023-01-06 02:15:43 +08:00
有 aop 啊,spring 事务是通过 autoproxy 方式的 aop 进行事务开启和提交的。
只需要在事务代理的外面再 aop 一下,不就能在事务提交后执行吗? |
9
Ayanokouji 2023-01-06 09:09:28 +08:00
spring TransactionalEventListener
|
10
vishun 2023-01-06 09:31:36 +08:00 1
springboot 自带事务提交后再执行的方法:
``` //执行 A 事务 TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronization() { @Override public void afterCommit() { B 相关代码 //这里会在 A 事务提交后,执行 B 事务 } } ); ``` |
11
HarrisonLee 2023-01-06 09:46:49 +08:00
楼上正解,正在使用这种方案
|
14
cryboy007 2023-01-06 10:30:47 +08:00
用事务提交事件即可
|