我已经阅读了本网站上交易的定义,以及其他一些外部资源。但在编写代码时,我很难解决事务的具体概念。
我有一个交易的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交易还调用了两种方法吗?也就是说,即使这些方法都没有被声明为事务。 没有将两个子方法声明为事务的潜在缺陷是什么? (因为它们看起来似乎已经成为其中的一部分)。
答案 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语句(它看起来不像,但不能仅仅通过查看代码就明确排除)。