春天@Transactional。将实体保存在主线程中,然后在一个事务中选择新线程

时间:2018-08-27 09:34:35

标签: java spring multithreading transactions spring-data-jpa

我的服务中有方法:

@Slf4j
@Component
public class ImportChargesHandler implements SendRequestHandler {
...

  @Override
  @Transactional
  public void process(SendRequestRequest request, String fullRequest) {

    String guid = sendRequestService.saveImportChargesRequest(...);

    taskExecutor.execute(() -> importChargesOperation.importChargesRequest(request, guid));

  }
}

在这种方法中,我有两个逻辑部分:

  1. saveImportChargesRequest-创建一些对象,保存在数据库中并返回id(guid)

  2. importChargesRequest-调用新线程。我通过保存的id(guid)并将其用于此方法(由guid选择)

但是,当我用第一种方法将对象保存在DB中并将ID传递给第二种方法时,当我通过ID进行选择进入第二种方法时,会得到异常(找不到实体)或成功结果。我认为发生这种情况的原因是,当我从previos方法中进行select-save方法时不会持久化数据,而且我也不知道这些数据。

将对象保存到数据库时,我尝试了saveAndFlush()-当我选择已刷新的数据并且可以选择它时。但是有时候我不能选择没有关系。

-> start main method with @Transactional
------transaction begin------------
   -> start fist internal method for save entity
      -> save entity
      -> flush
      -> return id
  -----start new thread------------
   -> start second method
   -> select entity by id(id from first method)
   -> exception(not found) or success select(it depends)
------transaction commit-----------

现在,我从主方法中删除了@Transactional。第一种和第二种方法具有@Transactional。我有这个logik

-> start main method without @Transactional
    ------transaction begin------------
       -> start fist internal method for save entity
          -> save entity
          -> flush
          -> return id
      ------transaction commit-----------
      -----start new thread------------
      ------transaction begin------------
       -> start second method
       -> select entity by id(id from first method)
       -> success select
    ------transaction commit-----------

但是我不知道是否正确实现此实现。以及如何解决第一个实现-在一个事务中将数据保存在主线程中并选择新线程?

1 个答案:

答案 0 :(得分:-1)

为什么需要第二个线程?请尝试删除第二个线程并仅使用一个。如果仍然需要第二个线程,则需要先提交第一个事务,然后才能像以前那样获得结果。您还必须知道,如果您需要清除所有保留的数据,则使用第二种方法将难以回滚事务。这就是为什么如果您考虑在一个线程中实现它的原因。