小编die*_*n07的帖子

来自Callable的CompletableFuture?

今天我尝试了CompletableFutureJava 8中的"new" ,当我找不到runAsync(Callable)方法时发现自己很困惑.我可以自己做,如下图所示,但为什么这(对我来说非常明显和有用的实用方法)缺失?上午失去了一些东西?

public static <T> CompletableFuture<T> asFuture(Callable<? extends T> callable, Executor executor) {
    CompletableFuture<T> future = new CompletableFuture<>();
    executor.execute(() -> {
        try {
            future.complete(callable.call());
        } catch (Throwable t) {
            future.completeExceptionally(t);
        }
    });
    return future;
}
Run Code Online (Sandbox Code Playgroud)

java concurrency java.util.concurrent java-8

11
推荐指数
1
解决办法
6903
查看次数

在Spring的@Transactional方法期间处理异常

我试图找出如何最好地结合使用Spring的持久性(以及潜在的其他)异常@Transactional。在这篇文章中,我将仅以一个简单的用户注册示例为例,这可能DataIntegrityViolationException由于用户名重复而引起。

我尝试过以下事情,但对我来说并不令人满意:

1.天真的方法:只捕获异常

val entity = UserEntity(...)
try {
    repo.save(entity)
} catch (e: DataIntegrityViolationException) {
    // not included: some checks for which constraint failed
    throw DuplicateUsername(username) // to be handled by the controller
}
Run Code Online (Sandbox Code Playgroud)

@Transactional方法中这是行不通的,因为持久性异常只有在提交事务后才会发生,这在spring事务包装器中我的服务方法之外发生。

2. EntityManager退出前冲洗

明确要求flushEntityManager在我的服务方法结束。这将强制写入数据库,并因此触发异常。但是,它可能是低效的,因为我现在必须注意不要无故在请求期间多次刷新。我也最好永远不要忘记它,否则例外会消失得无影无踪。

3.进行两个服务类别

@Transactional方法放在单独的spring bean中,并在主服务中尝试捕获它们。这很奇怪,因为我必须注意将代码的一部分放在A位置,另一部分放在B位置。

4.装DataIntegrityViolationException上控制器

就是不行。控制器在处理数据库中的异常方面没有任何业务(色相)。

5.不要抓 DataIntegrityViolationException

我已经在网上看到了一些资源,尤其是与Hibernate结合使用时,这表明捕获此异常是错误的,应该在保存之前检查条件(即,检查用户名是否存在手动查询)。即使在进行事务处理时,这在并发方案中也不起作用。是的,您将获得交易的一致性,但是DataIntegrityViolationException当“其他人首先出现”时,您仍然会获得一致性。因此,这不是可接受的解决方案。

7.不要使用声明式事务管理

使用Spring TransactionTemplate代替@Transactional。这是唯一令人满意的解决方案。但是,使用它比“仅仅抛出@Transactional方法”要笨拙得多,甚至Spring文档似乎也会使您偏向使用@Transactional

我想要一些有关如何最好地处理这种情况的建议。我最后提出的解决方案还有更好的选择吗?

java spring hibernate transactions

8
推荐指数
1
解决办法
611
查看次数