2017-09-13 18 views
2

我剛剛發現了一段代碼看起來如下:@Transactional在服務中的使用,當方法僅從數據庫中提取數據時。

@Transactional 
public List<Foo> giveMeFooMatchingSomeConstraints(Long param1, String param2) { 
List<Bar> bars = barDao.findBars(param1, param2); 
List<Foo> foos = fooDao.findFoosByBarIds(barService.getIds(bars)); 
return foos; 
} 

我只是好奇,什麼是在情況下,使用@Transactional當一個方法只獲取數據並不會改變他們的目的。這樣的方法就像上面那樣好嗎?

+0

可能的重複[爲什麼我需要在Hibernate中的事務處理只讀操作?](https://stackoverflow.com/questions/13539213/why-do-i-need-transaction-in-hibernate-forread -only-operation) – soorapadman

+0

用於獲取數據,不需要使用Transactional註釋,只要我們必須堅持多個表,那個時候只能使用Transactional。 – Balasubramanian

回答

1

是的,當您不使用Open*InView並在您的方法中使用惰性關係時,它是有意義的。

說我們這些實體與一個一對多的關係界定:

@Entity(name = "user") 
static class User extends AbstractPersistable<String> { 
    private String username; 

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) //by default fetching is lazy 
    @JoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "fk_user_roles")) 
    private Set<Role> roles = new HashSet<>(); 

    public Set<Role> getRoles() { 
     return this.roles; 
    } 
} 

@Entity(name = "role") 
static class Role extends AbstractPersistable<String> { 
    private String name; 

    private Role() { 
    } 

    public Role(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return this.name; 
    } 
} 

存儲庫訪問它們:

interface UserDao extends JpaRepository<User, String> {} 

和一些數據處理服務 - 檢索所有的用戶,循環槽和他們抓住所有的角色:

@Service 
static class UserService { 
    private final UserDao userDao; 

    UserService(UserDao userDao) { 
     this.userDao = userDao; 
    } 

    @Transactional // <--- 
    public Set<String> findUserRoles() { 
     final List<User> users = this.userDao.findAll(); 
     return users.stream() 
       .flatMap(user -> user.roles.stream()) 
       .map(Role::getName) 
       .collect(Collectors.toSet()); 
    } 
} 

刪除@Transactional到請參閱LazyInitializationExceptionno Session消息,因爲沒有人打開它。

爲了避免這種情況的混亂是更好,因爲只讀明確標記事務:

@Transactional(readOnly = true) 

所以讀者會知道,這種方法無意修改任何數據,但交易(會話)仍然需要。

Full example

+0

很好的解釋,在這種情況下使用@Transactional的原因現在很明顯。我喜歡你提供的例子的例子,謝謝! – pidabrow

相關問題