0

如何使用 iBatis 和 Spring实现涉及多个数据库操作到 >1 个表的事务?

让我详细解释一下:
我有 2 个表 A 和 B 具有主从关系。[单个数据库中的两个表]。

/* 表 A: */

a_id [主键]
[加其他列]

/* 表 B: */

b_id [Primary Key]  
a_id [Foreign Key = PK of table A]  
[plus other columns]  

在我的 Dao 中,我有以下方法(我使用 iBatis sqlMap 来执行数据库操作):

insertA();  
insertB();  
updateA();  
updateB();  
deleteA();  
deleteB();  

上述每个操作都是原子的(& 可以由客户端调用& 提交到数据库中 - 通过 Spring/iBatis)。

到目前为止,一切正常![即我能够在每个表上执行单独的插入/更新/删除。]

-- 接下来,我需要将上述两个 DB 操作组合为一个 ATOMIC 操作;
这是我想从 SVC 层实现的目标:

start Tranaction  
    operation on Table-A (via method of Dao class) - op #1  
    operation on Table-B (via method of Dao class) - op #2  
end Transaction  

示例 1:

start Tranaction  
    insertA();  
    insertB();  
end Transaction  

示例 2:

start Tranaction  
    updateA();  
    updateB();  
end Transaction  

在这里,如果 op#2 失败,我希望 op#1 也被回滚。即完全回滚。

因此,我在 Service 层中编写了额外的方法,它调用了上面的 DAO 方法。在运行(Svc)代码之前,我手动 [通过 cmd-line] 更改数据库上的一些数据,因此由于 DB 约束,第二次操作失败。

现在,op #2 [Table-B] 失败,但 op #1 已在 DB 中提交。即没有完全回滚,只有部分回滚。

如果 op#2 失败,op#1 不应该也回滚吗?

这是我在 ApplicationContext.xml 中使用的内容:

  • “DataSourceTransactionManager” [Spring] 用于事务。
  • iBatis 2.3.x [SqlMapClient]
  • 春天 3.0
  • DefaultAutoCommit 设置为 FALSE。
  • 在“tx:method”中:[要执行 ATOMIC 操作的服务方法)
    propagation="REQUIRED" [也尝试使用其他值,但没有用]
    rollback-for=Exception-Name-for-which-to-rollback

还有什么需要做的吗?
难道我做错了什么?
这是正确的方法还是有更好的选择?

4

1 回答 1

0

<

在我看来,你应该考虑数据完整性,如果 op #2 使系统失去数据完整性,那么它应该根据 op #1 回滚。

要实现您想要的,只需在 try/catch 块上调用 op #1 和 #2、wrapper #2,如下所示:

try {

    start Tranaction ;
    //pkA is primary key of A
    Object pkA = insertA();  
    updateA(pkA);  

    try {
        Object pkB = insertB(pkA); 
        updateB(pkB);  
    }
    catch(Exception e) {
        logger.ERROR("Error when inserting and updating B.Ignore. ",e);
    }
    commit transaction;
}
catch(Exception e) {
   logger.ERROR(e);
   rollback Transaction;
}

HTH。

于 2012-06-26T07:47:48.587 回答