2

我正在使用我在网上找到的以下代码(此处)作为 JTA 事务处理的示例:

// Get a UserTransaction
        UserTransaction txn = new InitialContext().lookup("java:comp/UserTransaction");
try {
     System.out.println("Starting top-level transaction.");

     txn.begin();
     stmtx = conn.createStatement(); // will be a tx-statement 

     stmtx.executeUpdate("INSERT INTO test_table (a, b) VALUES (1,2)");
     stmtx.executeUpdate("INSERT INTO test_table2 (a, b) VALUES (3,4)");

     System.out.print("\nNow attempting to rollback changes.");

     txn.rollback();
}

一般来说,我对上面示例中的 JTA 有几个问题:

  1. 我认为说txn.begin然后回滚的全部意义在于能够(显然)回滚两个 SQL 语句是否正确?
  2. 每个更新查询都是 TRANSACTIONS 本身,对吧?他们一定已经成功了,这样我们才能在底部回滚调用。好吧,如果他们成功了,即承诺,我们怎么能突然把他们回滚呢?
  3. 最重要的问题:当我们说 时会发生什么txn.begin()?我从 JTA API 了解到,它应该通过TransactionManager实例向调用线程注册此事务。TM 是如何与 TM 联系起来的UserTransaction?最后,txn 是如何知道我们修改了 DB 两次并且能够与 DB 对话以将其回滚的事实?我们还没有向它注册 ANY ResourceManager,所以它不应该知道任何资源正在发挥作用......

我在这里有点迷路,所以任何信息都将不胜感激......问题3最困扰我。

4

2 回答 2

1
  1. 是的,或者事件只是一个。也是在最后提交事务的能力,因此其他并发事务只能看到事务提交后的新状态,而不是事务开始和结束之间的所有临时状态(即 I在酸中)

  2. 不,更新就是更新。它作为您之前开始的事务的一部分执行。如果其中一个不成功,您将遇到异常,并且仍然可以选择提交事务(即提交所有先前的更新),或回滚事务(即取消所有先前的更新)。

  3. UserTransaction 大概有对其事务管理器的引用。在 Java EE 环境中从 DataSource 获得连接时,DataSource 链接到 Java EE 容器的事务管理器,回滚 JTA 事务将使用 XA 协议回滚期间对所有数据源所做的所有操作交易。那是容器的事,不是你的事。

于 2013-06-05T11:51:33.923 回答
1

关于交易有很多东西要学,但也许我可以给你一个先机:

  1. 是的。但您通常只想在出现问题时回滚 - 由于技术问题(语法错误、未找到表、段溢出等)或应用程序逻辑问题(客户例如,没有足够的资金用于所有订单行项目)。
  2. 鉴于禁用自动提交模式,插入不会在您实际提交之前提交。它们使用具有复杂的多版本并发控制 (MVCC) 的预写日志(PostgreSQL、InnoDB-Engine、Oracle)临时应用于数据库,该控制确定每个事务客户端可以看到的数据库状态。一个非常有趣的话题:-)。
  3. UserTransaction 已注册到您当前的线程。资源(即数据库或消息服务)通过 UserTransaction 自行注册。这通常仅在您使用分布式事务(XA 事务,2PC)时才需要。

我建议好好阅读 SQL 编程(例如Head First SQL)并查看Java EE 6 教程

于 2013-06-05T11:58:13.697 回答