2

我将 JDBC 与 mysql 一起使用。我在单个事务中进行了一系列非常复杂的插入和更新。这似乎在大多数情况下都有效,但在大约 1% 的情况下,我发现我的一个表中的数据处于不一致状态。

如果发生错误,我将回滚事务,但不确定如何开始调试。我的设置通常如下所示:

try {
    conn.setAutoCommit(false);  

    PreparedStatement stmt1 = conn.prepareStatement("insert into table1");
    stmt1.executeUpdate();
    stmt1.close();

    PreparedStatement stmt2 = conn.prepareStatement("update table2");
    stmt2.executeUpdate();
    stmt2.close();

    ... more statements ...

    conn.commit();
} 
catch (Exception ex) {
    conn.rollback();
}

我正在使用 2010 版本的 mysql。我可能会尝试更新它,但我觉得它更多的是我的应用程序代码中导致不一致的东西。

是否有任何我可能会在数据库级别发现有用的调试工具来提供帮助?还有其他指针吗?我正在使用所有默认设置的 JDBC,我想知道在这种情况下是否需要使用更严格的事务级别?

谢谢

----- 注意 ----- 我所有的表都是 InnoDb。

4

2 回答 2

0

嗯..有趣。是的,它应该工作。我们在多个表中多次使用非常大的事务,甚至从未经历过奇怪的事情......
你确定不是你造成了不一致(不管这意味着什么,你没有指定这个)?通过简单地插入/更新错误的东西?:-)

只是一个想法——我们多次遇到这个问题。解决死锁。用于处理该问题的数据库服务器。如果您有多个并行线程并且事务块正在操作更多表,则发生死锁的机会会更高。在这种情况下,您的一些事务可能会被数据库服务器本身中止(并回滚)。这些交易将导致错误。

您在上面编写的代码仅在异常情况下回滚(中止的事务已经回滚,所以它不会做太多......),但是您是否尝试过打印/记录异常?如果不是,你应该。

当然,事务是彼此分开运行的。但这可以解释为什么你在只有 1-2% 的情况下会遇到这种奇怪的行为......

你也应该检查你的 mysql 服务器的日志。服务器本身也可能由于任何原因而失败。还有一个提示:您可以尝试运行“mysqltop”(或“mtop”,希望我正确记住了这个工具的名称..)。这能够监控并向您展示数据库服务器内部发生的情况。但是它主要用于跟踪我们的 sql 的性能,这也显示了失败。也许运行这个也可以帮助你......

于 2013-02-16T20:53:11.617 回答
0

也许您在语句中使用了 DDL(创建表、更改表等)?

我不确定 MySQL,但它可能无法回滚 DDL 语句。

例如:

  • PostgreSQL 可以回滚 DDL,
  • Oracle 在执行 DDL 之前执行提交。

见这里:http ://dev.mysql.com/doc/refman/5.0/en/cannot-roll-back.html

于 2013-02-16T21:07:21.037 回答