是什么使事务成为Spring / Java中的事务(特定场景)?

时间:2012-01-16 16:39:37

标签: java spring transactions

我已经阅读了本网站上交易的定义,以及其他一些外部资源。但在编写代码时,我很难解决事务的具体概念。

我有一个交易的BuyService类。 BuyService类声明为transactional,其唯一的方法是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类:

public class InvoiceService implements InvoiceServiceInterface
{   
private InvoiceServiceDaoInterface InvoiceServiceDao;

public void setInvoiceServiceDao(InvoiceServiceDaoInterface InvoiceServiceDao)
{
    this.InvoiceServiceDao = InvoiceServiceDao;
}

@Override
public void writeInvoice(Widget purchasedWidget)
{
    Date purchaseDate = new Date(new java.util.Date().getTime());
    String isbn = purchasedWidget.getIsbn();
    Purchases newPurchase = new Purchases(purchaseDate, isbn);
    this.InvoiceServiceDao.savePurchase(newPurchase);
}
} 

buyWidget交易还调用了两种方法吗?也就是说,即使这些方法都没有被声明为事务。 没有将两个子方法声明为事务的潜在缺陷是什么? (因为它们看起来似乎已经成为其中的一部分)。

2 个答案:

答案 0 :(得分:3)

  

方法deleteWidget和writeInvoice本身也是事务吗?

他们将参与buyWidget交易,但他们本身并不是交易性的

  

buyWidget交易是否也调用了这两种方法?

事务在进入buyWidget方法之前启动,并在方法完成之前停止或回滚。这两种方法将参与buyWidget事务,但本身不是事务。

答案 1 :(得分:1)

  

buyWidget交易还调用了两种方法吗?

的所有方法都不是交易。注释@Transactional(propagation=Propagation.REQUIRED)表示" Support a current transaction, create a new one if none exists."此事务将包含buyWidget()方法调用的任何内容。基本上,当进入方法时,一个事务被启动,当它退出时,该事务将被提交(如果一切正常)或回滚(如果抛出异常,数据库端出现问题,或者事务被滚动)通过Java代码返回)。

  

即使这些方法都没有被声明为事务。

只要这些方法在知道JTA的数据库上运行,它就可以使用现有的事务。

  

未将两个子方法声明为事务有哪些潜在的缺陷? (因为它们看起来似乎已经成为其中的一部分)。

如果直接调用这些方法,它们将不会成为事务的一部分。这可能导致数据库的状态不一致,如果这些方法导致多个SQL语句(它看起来不像,但不能仅仅通过查看代码就明确排除)。