[英]Spring transaction and try catch blocks
我對 Kotlin 和 Spring 非常陌生,並且有一個非常基本的疑問。 考慮這樣的 function:
@transaction
fun accept() {
try {
write to table A
throw Exception()
} catch(){
write to table B
}
}
問題:我知道B表寫會成功,但是A表會寫成功嗎? 為什么? 任何指向
Spring 對異常的“含義”有點奇怪。 它的作用如下。 事務方法在退出之前不會提交任何內容。 即:
@transaction
fun accept() {
write to table A
while (true) {} // loop forever
}
微不足道地從不實際提交任何東西,這可能很明顯。 否則,該方法退出,它可以通過以下三種方式之一退出:
throw new RuntimeException()
)。throw new IOException()
添加到 accept 方法的末尾,當然您的方法可以這樣做。在 java 中意味着它必須當然,被聲明為void accept() throws IOException {}
。kotlin中不存在已檢查和未檢查的概念 - 在 kotlin 中,所有異常都是“未檢查”,有效。 但是,spring 沒有 go:“OOoooohhhh,kotlin 用戶,我將把所有事情都視為未選中的事務,即拋出任何異常,” 不,因此,即使您只編寫 kotlin,您也必須了解檢查異常是什么。
Unchecked exceptions are all throwables that have in their type hierarchy either java.lang.Error
(such as java.lang.InternalError
, which extends jlError
), or java.lang.RuntimeException
, such as NullPointerException
.
所有其他投擲物都被“檢查”。 比如IOException
,它擴展了 Exception。 它擴展了 Throwable。 檢查Exception
本身。
注意:您可以添加攔截器等來改變這種行為; “檢查異常意味着我們需要提交,檢查意味着我們需要中止”只是默認行為。
如果“寫入表 A”成功,那么是的,它將持續存在。
為什么? 因為事務划分是由對異常起作用的攔截器完成的,並且在您的代碼中沒有攔截器會看到該異常,因為它們只能圍繞那些“寫入表 X”調用(如果這些調用是通過可攔截代碼完成的)或accept()
執行。
讓我嘗試添加更多細節:
一般來說,您可以在概念上認為攔截器看起來像這樣(它們看起來不同,但示例用於說明這一點 - 我還將使用 Java 代碼,因為我對 Kotlin 不太熟悉):
void runInTransaction(Runnable interceptedCode) {
Transaction tx = startTransaction();
try {
interceptedCode.run();
tx.commit();
} catch( Exception e) { //kept simple for illustration purposes, in reality this is way more complex
tx.rollback();
}
}
然后你會這樣稱呼它:
runInTransaction(() -> accept());
如您所見,由於異常僅在accept()
中被拋出和捕獲 - 因此不會離開方法 - 攔截器甚至不會看到它,因此將提交事務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.