从多个线程访问Spring @Transactional服务

时间:2014-04-11 10:23:28

标签: spring transactions thread-safety

我想知道以下是否安全。

访问一堆DAOS / hibernate实体的常用Spring服务类:

@Transactional
public class MyService {
    ...
    public SomeObject readStuffFromDB(String key)  {
    ...
    //return some records from the DB via hibernate entity etc
}

应用程序中连接服务的类:

public class ServiceHolder {
    private MyService myService;

    private SomeOtherObject multiThreadedMethod() {

        ...
        //calls myService.readStuffFromDB() and uses the results 
        //to return something useful
}

将从多个线程池线程调用multiThreadedMethod。我想知道multiThreadedMethod在调用myService时是否安全。 它不会对DB进行任何修改 - 只读。

如果两个线程在同一时间调用myService.readStuffFromDB()会发生什么?是否会从某个地方抛出并发修改异常?

我一直在运行它没有任何问题,但我不能100%确定它会一直有效。

1 个答案:

答案 0 :(得分:1)

是的,只要您的服务bean被定义为singleton(默认且正确),您将在同一时间调用同一个对象,但您不应该依赖服务中的本地变量。所以这些方法应该以他们可以独立工作的方式编写(这里不需要互斥)。如果您调用db并尝试执行任何操作,则不会发生任何事情,因为每个线程都会收到实体管理器的新实例。如果您在同一时间修改了db并且抛出了任何类型的db异常,那么您将获得一个完全正常的回滚异常。

entityManager.persist()会或多或少地执行entityManager.getEntityManagerAssignedToCurrentThread()。persist()

这是一个代理而不是真实的对象。所以你很安全:)