0

我的班级被定义为

@Transactional
@Service
public class InteractionHistoryServiceImpl implements InteractionHistoryService {

在该类中,我有一个方法可以对单独的 DB2 存储过程进行 4 次单独调用,如下所示(伪):

@Override
public void createInteractionHistory(String userId, String userChannel,
        CreateInteractionHistoryRequestPayload requestPayload) {

dao.createInteractionHistory(userId, userChannel, viewableBy,
            interactCode, systemCreationDateTime, partyGrpId,
            interactionHistoryController);

dao.createInteractionHistoryDetails(userId, interactonDescription, interactionHistoryController);

dao.createInteractionHistoryDetailsLink(userId, componentId, objectId, objectType, correspondanceType, direction, interactionHistoryController);

dao.createInteractionHistoryDetailsLink(userId, componentId, documentId, DOCUMENT, correspondenceType, direction, interactionHistoryController);
}

现在在最后的调用中,我通过传递一个太大的字段宽度来强制数据库中的异常,因此它根本无法调用 proc。这被捕获并转换为扩展 RuntimeException 的系统异常。

我在异常发生后调试了这段代码,它输入到 spring 框架中并且似乎正在回滚。

当我检查基础表时,我可以看到所有以前存储的过程都成功并且没有回滚,但最终调用没有成功。

这给我留下了不一致的数据和令人头疼的问题,因为我的理解是这些应该全部或全部处理提交/回滚。

我检查了存储的过程,数据库中没有提交。

这里有什么想法吗?

4

1 回答 1

1

您需要考虑您的交易边界。事务边界通常是执行 BEGIN TRANSACTION 和 COMMIT / ROLLBACK 语句的地方,它不完全取决于 Spring,但也可能依赖于数据库实现。

在类级别指定@Transactional 表示类的每个公共方法都具有声明性事务边界(即:事务将在方法执行之前启动,在方法完成时提交/在发生异常时回滚)

在您的情况下,您似乎没有将 4 个createInteractionHistory调用包含在一个事务中——而是它们是 4 个单独的事务。因此,当最后一个失败时,前 3 个已经成功。

然而,即使您将所有这 4 个调用包含在单个事务中,也不能保证所有 SQL 都将在一个事务中运行,因为这取决于存储过程中的代码以及 DB2 如何绘制事务边界。

我建议您花一些时间在 Spring 事务边界和传播主题上——还有 DB2 事务。spring 手册的第 11 章是一个很好的参考。

于 2013-01-23T03:56:49.207 回答