2012-01-16 55 views
0

我已閱讀本網站上的交易定義以及一些其他外部來源。但是在編寫代碼時,我很難與交易的具體概念作鬥爭。什麼使事務成爲Spring/Java(特定場景)中的事務?

我有一個BuyService類是事務性的。 BuyService類被聲明爲事務性的,唯一的方法是buyWidget(String widgetId)。此方法調用ExampleService類,該類具有deleteWidgit(String widgetId)方法。它還調用InvoiceService類,該類使用writeInvoice(String widgitId)方法。下面是代碼:

BuyService類:

import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

@Transactional 
public class BuyService implements BuyServiceInterface 
{ 
private ExampleServiceInterface exampleService; 
private InvoiceServiceInterface invoiceService; 

public void setExampleService(ExampleServiceInterface exampleService) 
{ 
    this.exampleService = exampleService; 
} 

public void setInvoiceService(InvoiceServiceInterface invoiceService) 
{ 
    this.invoiceService = invoiceService; 
} 

@Override 
@Transactional(propagation=Propagation.REQUIRED) 
public void buyWidget(Widget widgetId) 
{ 
    try 
    { 
     Widget purchasedWidget = this.exampleService.getWidgetById(String widgetId); 
     this.exampleService.deleteWidget(purchasedWidget); 
     this.invoiceService.writeInvoice(purchasedWidget); 
    } 
    catch (WidgetNotFoundException e) 
    { 
     System.out.println("Widget with widgetId " + widgetId + " not found."); 
    } 
} 
} 

我敢肯定的是,buyWidget方法構成了交易。它需要刪除數據庫中的小部件(在exampleService中)以及將數據插入購買數據庫(在invoiceService中)。但在此之後,我對術語感到困惑。方法deleteWidget和writeInvoice自己的事務嗎?

ExampleService類:

public class ExampleService implements ExampleServiceInterface 
    { 
private ExampleServiceDaoInterface dao; 

public void setExampleServiceDao(ExampleServiceDaoInterface dao) 
{ 
    this.dao = dao; 
} 

@Override 
public void deleteWidget(Widget oldWidget) 
     throws WidgetNotFoundException 
{ 
    this.dao.delete(oldWidget); 
} 

@Override 
public Widget getWidgetById(String widgetId) 
{ 
    return this.dao.getById(widgetId); 
} 
} 

InvoiceService類:

​​

是兩種方法buyWidget交易呼籲呢?也就是說,即使這些方法都沒有被聲明爲事務。 沒有將兩個子方法聲明爲交易有什麼潛在的缺陷? (因爲它們顯然已經成爲一部分)。

+0

通常是一個好主意,省去代碼不直接與問題,如訪問者/ mutators /例外等代碼 –

回答

3

方法deleteWidget和writeInvoice自己的事務嗎?

他們將參加buyWidget交易的一部分,但它們本身並不是事務

是兩種方法buyWidget交易呼籲呢?

交易在進入buyWidget方法之前開始並在方法完成之前停止或回滾。這兩種方法將參與buyWidget交易,但它們本身不是交易。

1

buyWidget事務也調用了這兩種方法嗎?

沒有任何方法交易。註釋@Transactional(propagation=Propagation.REQUIRED)意味着" Support a current transaction, create a new one if none exists."此交易將包括任何從buyWidget()方法調用的任何東西。基本上,當進入方法時,一個事務開始,當它退出時,這個事務將被提交(如果一切正常)或回退(如果拋出了一個異常,DB端出現問題或事務被滾動通過Java代碼返回)。

也就是說,即使這兩種方法都沒有聲明爲事務。

只要這些方法在知道JTA的DB上運行,它就可以與現有事務一起工作。

如果不將兩個子方法聲明爲事務,有什麼潛在的缺陷? (因爲它們顯然已經成爲一部分)。

如果這些方法是直接調用的,它們將不會成爲事務的一部分。如果這些方法導致多個SQL語句(它看起來不像這樣,但不能僅僅通過查看代碼就可以明確排除),這可能會導致數據庫的狀態不一致。

+0

我打算只在購買小部件時使用這兩種方法。所以只有在有直接調用子方法的用例的情況下才有風險......這是否正確?無論如何,我會做一個精神記錄來確保訪問數據庫的所有方法都是交易。最後,如果這兩個子方法在交易中會有什麼不同? – harryo

+0

@user,一個好的設計是將邏輯分成一個* repository *和一個* service *實現(服務使用倉庫,倉庫接口數據庫),並且只做* service * transactional。 –

+0

@JohanSjoberg;只是爲了確認,你是指「存儲庫和服務」模式?我對你的推薦進行了在線搜索,這似乎是你的意思。但在開始調查這個概念之前,我需要確定。 – harryo