【问题标题】:ACID Problems in a Multithreaded Environment多线程环境中的 ACID 问题
【发布时间】:2011-11-12 18:53:30
【问题描述】:

我有一个多线程 Java 应用程序,它在 MySQL 数据库上执行大量并行 CRUD 操作。如 MySQL 手册中所述,InnoDB 表结构应确保事务按照 ACID 原则执行。但是我仍然有问题,因为有时更新会丢失。这是我使用的示例存储过程之一:

DELIMITER //
CREATE PROCEDURE *** (
    _*** INT,
    _*** INT,
    _*** INT,
    _*** INT
)
BEGIN
  START TRANSACTION;

    UPDATE `***` 
    SET  
      `***`.`***` = `***`.`***` + _***,  
      `***`.`***` = `***`.`***` + _*** + _***,  
      `***`.`***` = DATE_ADD(NOW(), INTERVAL _*** SECOND)  
    WHERE `***`.`***` = _***;

  COMMIT;
END;
// 
DELIMITER ;

【问题讨论】:

  • 对 ACID 中的 I 感到失望。事务的隔离是一个复杂的问题。尝试将事务级别设置为可序列化,以避免对同一行进行并发更新,或者放置一些行锁。
  • @regilero:你应该把它作为答案! Vilius:另请阅读:mpopp.net/2005/12/…
  • 我已经阅读了有关事务级别的文章和其他一些文章,但它仍然对我不起作用......我将重新考虑 Java 应用程序的设计,并将 MySQL 服务器更新为5.5 分支。

标签: java mysql multithreading innodb acid


【解决方案1】:

JDBC类是不可重入的,所以连接、语句等对象实例的使用必须同步,不能被多个线程同时使用。

使用连接池是简化对数据库的并发访问的好方法。

编辑

如果您确定线程从不使用相同的连接,您可以检查

  • 池可能没有连接吗?是怎么处理的?
  • 是否有 2 个更新作用于第一个被覆盖的同一记录?
  • 您是否捕获所有异常并将它们记录到您的工作人员中?

【讨论】:

  • 可悲的是,我已经在使用连接池 (BoneCP) ...我还使用 ThreadPoolExecutor 来处理执行 SQL 操作的不同线程 - 用于 ThreadPoolExecutor 的工作队列有效以先进先出的方式。我认为这两种技术将确保对数据库的无错误并发访问。
  • 感谢您的建议!我基本上认为第二个要点会导致问题......这就是为什么我认为错误发生在 MySQL 服务器而不是 Java Connection Pool/ThreadExecutor 的原因。我还听说 MySQL 5.5 对 InnoDB 锁定有更好的支持?这是真的吗? (我还在用 5.1.x)
猜你喜欢
  • 2020-02-08
  • 1970-01-01
  • 2014-01-20
  • 2011-03-07
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-10
相关资源
最近更新 更多