我们正在开发在线时间表应用程序。一个时间表可以由多个用户同时编辑。这里有一个非常重要的业务约束。一天只能有三件事。
从技术上讲和简化来说,数据库中有一个表,列为:| id | event | date |。应用程序运行在事务"select…"数……如果result小于3,则插入新事件。
哪些方法可以保证两个线程不会在一天内创建四个事件?这是一个典型的检查和写入问题。我们想知道如何在数据库级别上解决这个问题?
使用事务并不能保证在第二个事务中另一个线程不会做同样的事情:检查事件数小于3并进行插入。锁整个表是不可接受的,因为它会减少响应时间、并发性等。
应用程序是在Java中使用Spring, Hibernate, MySQL开发的。
提前感谢您的建议
对于阻塞进程,您应该使用Select…FOR UPDATE语句。
的例子:
//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
对于您的数据模型,您可以使用check约束来计算行数。我知道MySQL本身不支持这种类型的约束,但是看起来可以用一个触发器来模拟它们
或者,您可以考虑使用days
表和events
表的不同数据模型。您可以使用days
的乐观锁定来确保第二个事务不会对数据有过时的理解。
由于您正在使用Spring,并且存在并发性问题,请尝试在Java层而不是在DB层同步执行。我们在尝试使用DB来维护并发时也遇到过类似的问题。
也许你可以在Java synchronized
中设置执行块,这样它就可以强制执行阻塞;在同步方法中,检查所有业务逻辑是否返回true。如果为true,则继续正常执行。