提交单个属性值而不是整个事务

时间:2018-11-15 12:25:13

标签: java sql oracle concurrency

我有一个Java程序,它与通过单个事务启动的DB(oracle)进行许多交互。我需要更新一列,例如某张表的Y表示X,并且应该提交而不是整个事务。

我之所以需要它,是因为当该Java程序执行某些操作并且在某处失败时,该Java程序完成的所有操作都会回退,但是当我在更新表中的列后确实在该Java程序中提交时X,那么它也将提交直到现在为止完成的事情,而我将无法享受整个事务的回滚。

该列的值是处理并发程序调用所必需的。

5 个答案:

答案 0 :(得分:3)

  

我需要更新一列,例如某张表的Y表示X,并且应该提交而不是整个交易。

您可以在autonomous transaction中执行X的更新。

CREATE PROCEDURE updateXofY(
  in_id IN X.ID%TYPE,
  in_y  IN X.Y%TYPE
)
AS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  UPDATE X
  SET   Y  = in_y
  WHERE id = in_id;
  COMMIT;
END updateXofY;
/

调用该过程后,它将更新表X的Y列和COMMIT自主事务,而无需提交调用事务。

这样做的缺点是COMMIT限制了自主事务,因此如果您ROLLBACK是主事务,那么它将不会ROLLBACK自主事务(因为它是自主的)。

答案 1 :(得分:0)

为什么您不能直接进行另一笔交易来完成“内部”工作。保持当前事务运行,并使用新事务来完成额外的工作。

除非外部事务失败,否则您也要回滚内部事务。在这种情况下,我认为您需要嵌套事务。

答案 2 :(得分:0)

自主交易是很好的建议。但是,您也可以在Java程序中打开第二个连接。在一个连接中处理更新/提交,在另一个连接中处理主要事务。

答案 3 :(得分:0)

对于裸JDBC,Martin Schapendonk提到的新Connection是必经之路。

使用Spring,Propagation#REQUIRES_NEW上的Transactional annotation可用。同样,使用EJB可以使用TransactionAttributeType#REQUIRES_NEW

答案 4 :(得分:-1)

事务背后的原因也太原子了。因此,除了保存值并在另一笔交易中进行更新之外,没有通用的方法。