Spring @Transaction和@Async用于数据库操作

时间:2018-05-16 00:39:23

标签: java spring asynchronous concurrency

在spring应用程序中,当我们收到消息@Service时,persist bean正在调用数据库操作以插入到数据库&并行@Service解析&处理消息。在这种情况下,persist正在使用@Transactional。为了使流并行,建议添加@Async for persist。

此外,每个保存方法都有@Aspect,由persist服务调用,用于记录&审计。

  • @Async是否适合数据库操作?
  • @Async是否会创建表锁?

1 个答案:

答案 0 :(得分:3)

所有@Async都会导致带注释的组件的方法在另一个线程上执行,它从池中获取线程(可以指定,因此您可以选择某些操作来拥有专用池)

@Async本身不会对锁定数据库表或与数据库相关的任何其他内容做任何事情。如果您想要数据库级锁定,则必须通过其他方式实现。如果希望调用使用事务,则必须在异步调用的组件上使用@Transactional注释。交易将与来电者的交易分开。当然,事务可能会导致数据库锁定,具体取决于隔离级别和数据库实现。

将@Async用于数据库工作很棘手。当jpa持久化实体通过线程传递时会发生一个陷阱,因为它们具有在新线程中实现的惰性属性(其中代理现在无效,因为它无法从旧线程获取到实体管理器)。如果在线程之间传递的东西是不可变的,那么它会更安全。

@Async增加了复杂性并且难以推理。竞争条件和死锁都有机会,如果你没有完全正确,那么就会发生不好的事情,你不能指望通过测试来发现问题。它没有网络,如果你想要任何基础设施来帮助进行异常处理,重试或其他恢复,你必须自己提供它。

所以不,我不一定称之为可取。这是一个很好的功能,在你的工具箱中可能对一些孤立的案例有帮助,但普遍使用似乎是一件坏事。如果您正在寻找无阻塞地保留数据的方法,还有其他选择。

相关问题