我每天都需要获取所有过期客户的列表并将它们插入到新表中,然后我需要将日期移动一个月,因此它们将在下个月再次处理。
当前我正在连续运行2个SQL查询
insert into history select * from customers where nextdate<CURDATE()
update customers set nextdate=calculation() where nextdate<CURDATE()
但是有时客户会更新,但不会插入历史记录。
考虑到该更新在mysql完成选择之前就开始运行。
[我正在使用Node js,他当前用于序列化的方法是,我正在update
的回调中运行insert
,但可能在代码实际运行之前就调用了insert。
并非每次都发生,但是我认为同时进行存储过程可以有所帮助,任何人都对此有一定的经验吗?
这里有两个问题。首先是您的SELECT和UPDATE不要等待,因为SELECT不会锁定表。您可以使用以下方法强制锁定阅读:
INSERT INTO history SELECT * FROM customers WHERE nextdate<CURDATE() FOR UPDATE;
有关锁定读取的更多信息,请参见https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html。>>
[第二个原因是,您可能还想了解transactions,它使您可以发出一批查询,以便使所有查询都可以提交,而没有一个都可以。
对于您的代码,您想添加用于发出事务的开始和结束命令:
START TRANSACTION; INSERT INTO history SELECT * FROM customers WHERE nextdate<CURDATE() FOR UPDATE; UPDATE customers SET nextdate=calculation() WHERE nextdate<CURDATE(); COMMIT;
有关此机制的所有详细信息,请参见https://dev.mysql.com/doc/refman/5.7/en/commit.html,从MySQL到Postgres到SQLite都支持。
您可以使用由nodejs提供的promise进行串联,也可以使用Async series