本文翻譯自:Where does the @Transactional annotation belong?
Should you place the @Transactional
in the DAO
classes and/or their methods or is it better to annotate the Service classes which are calling using the DAO objects? 你應該將@Transactional
放在DAO
類和/或它們的方法中,還是更好地註釋使用DAO對象調用的Service類? Or does it make sense to annotate both "layers"? 或者註釋兩個“層”是否有意義?
#1樓
參考:https://stackoom.com/question/4Wj4/Transactional註釋在哪裏
#2樓
I think transactions belong on the Service layer. 我認爲交易屬於服務層。 It's the one that knows about units of work and use cases. 這是瞭解工作單位和用例的人。 It's the right answer if you have several DAOs injected into a Service that need to work together in a single transaction. 如果您將幾個DAO注入到需要在單個事務中協同工作的服務中,那麼這是正確的答案。
#3樓
The normal case would be to annotate on a service layer level, but this really depends on your requirements. 通常的情況是在服務層級註釋,但這實際上取決於您的要求。
Annotating on a service layer will result in longer transactions than annotating on DAO level. 在服務層上添加註釋將導致比在DAO級別上註釋更長的事務。 Depending on the transaction isolation level that can youse problems, as concurrent transactions wont see each other's changes in eg. 取決於可以解決問題的事務隔離級別,因爲併發事務不會看到彼此的更改,例如。 REPEATABLE READ. 可重複閱讀。
Annotating on the DAOs will keep the transactions as short as possible, with the drawback that the functionality your service layer is exposing wont be done in a single (rollbackable) transaction. 對DAO進行註釋將使事務儘可能短,但缺點是服務層公開的功能不會在單個(可回滾)事務中完成。
It does not make sense to annotate both layers if the propagation mode is set to default. 如果傳播模式設置爲默認值,則註釋兩個圖層沒有意義。
#4樓
Transactional Annotations should be placed around all operations that are inseparable. Transactional Annotations應圍繞所有不可分割的操作。
For example, your call is "change password". 例如,您的電話是“更改密碼”。 That consists of two operations 這包括兩個操作
- Change the password. 更改密碼。
- Audit the change. 審覈變更。
- Email the client that the password has changed. 通過電子郵件向客戶端發送密碼已更改。
So in the above, if the audit fails, then should the password change also fail? 那麼在上面,如果審覈失敗,那麼密碼更改是否也會失敗? If so, then the transaction should be around 1 and 2 (so at the service layer). 如果是這樣,那麼交易應該在1和2附近(所以在服務層)。 If the email fails (probably should have some kind of fail safe on this so it won't fail) then should it roll back the change password and the audit? 如果電子郵件失敗(可能應該具有某種故障安全性,因此它不會失敗)那麼它應該回滾更改密碼和審覈嗎?
These are the kind of questions you need to be asking when deciding where to put the @Transactional
. 這些是您在決定將@Transactional
放在何處時需要提出的問題。
#5樓
For Transaction in database level 對於數據庫級別的事務
mostly I used @Transactional
in DAO's just on method level, so configuration can be specifically for a method / using default (required) 大多數時候我只在方法級別使用DAO的@Transactional
,所以配置可以專門用於方法/使用默認值(必需)
DAO's method that get data fetch (select .. ) - don't need
@Transactional
this can lead to some overhead because of transaction interceptor / and AOP proxy that need to be executed as well. DAO的獲取數據的方法(選擇..) - 不需要@Transactional
這可能會導致一些開銷,因爲事務攔截器/和AOP代理也需要執行。DAO's methods that do insert / update will get
@Transactional
DAO的插入/更新方法將獲得@Transactional
very good blog on transctional 關於transctional的非常好的博客
For application level - 對於應用程序級別
I am using transactional for business logic I would like to be able rolback in case of unexpected error 我正在使用事務性的業務邏輯我希望能夠在意外錯誤的情況下回滾
@Transactional(rollbackFor={MyApplicationException.class})
public void myMethod(){
try {
//service logic here
} catch(Throwable e) {
log.error(e)
throw new MyApplicationException(..);
}
}
#6樓
I place the @Transactional
on the @Service
layer and set rollbackFor
any exception and readOnly
to optimize the transaction further. 我將@Transactional
放在@Service
層並設置rollbackFor
任何異常和readOnly
以進一步優化事務。
By default @Transactional
will only look for RuntimeException
(Unchecked Exceptions), by setting rollback to Exception.class
(Checked Exceptions) it will rollback for any exception. 默認情況下,@ @Transactional
將僅查找RuntimeException
(未經檢查的異常),通過將回滾設置爲Exception.class
(Checked Exceptions),它將回滾任何異常。
@Transactional(readOnly = false, rollbackFor = Exception.class)
See Checked vs. Unchecked Exceptions . 請參閱已檢查與未檢查的例外 。