0

我们正在开发在线日程应用程序。一个时间表可以由多个用户同时编辑。有一个非常重要的业务约束。一天内必须只有三个事件。

从技术上讲和简化,数据库中有一个带有列的表:| 编号 | 活动 | 日期|。应用程序在事务“select...count...where...”中运行,如果结果小于 3,则插入新事件。

可以使用哪些方法来保证两个线程不会在一天内创建四个事件?这是一个经典的 check-and-write 问题。我们想知道如何在数据库级别解决它?

使用事务并不能保证在第二个事务中另一个线程不会做同样的事情:检查事件数是否小于 3 并进行插入。锁定整个表是不可接受的,因为它会减少响应时间、并发性等。

应用程序是使用 Spring、Hibernate、MySQL 用 Ja​​va 开发的。

提前感谢您的任何建议。

4

3 回答 3

0

使用您的数据模型,您可以使用检查约束来计算行数。AFAIK MySQL本身并不支持这种类型的约束,但看起来可以用触发器模拟它们

或者,您可以考虑使用一个days表和一个events表的不同数据模型。您可以使用乐观锁定days确保第二个事务没有对数据的过时理解。

于 2011-08-24T12:08:55.093 回答
0

对于阻塞进程,您应该使用 Select ... FOR UPDATE 语句。但这仅适用于innodb。

例子:

//java logic
try {
    //mysql logic
    start transaction;
    select * from where 'some condition' FOR UPDATE
    INSERT INTO TABLE ....    
    commit;
//java logic
catch (Exception e) {
    rollback;
}

查看有关特定行锁定的更多信息http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html

于 2011-08-24T12:33:42.353 回答
0

由于您正在使用 Spring,并且由于存在并发问题,因此请尝试在 Java 层而不是 DB 层同步执行。在尝试使用数据库来维护并发时,我们遇到了类似的问题。

也许您可以在 Java 中制作执行块,synchronized以便它强制执行阻塞;在同步方法中,检查所有业务逻辑是否返回 true。如果为真,则继续正常执行。如果为 false,则异常中止。

于 2011-08-24T13:35:23.500 回答