我有多个独立的进程,每个进程都向MySQL数据库提交大容量插入查询(数百万行),但是让它们并发运行要比按顺序运行慢得多。
如何限制这些查询的执行,以便一次只能按顺序执行一个查询?
我曾想过检查PROCESSLIST是否包含任何正在运行的查询,但这可能不是真正的先来、先排队、先服务的正确排队查询的最佳方式。
我正在使用C#和.NET的MySQL连接器。
发布于 2020-06-23 16:54:33
我不确定这是否会有帮助,但我来看看。我遇到了一个类似的问题,我的程序抛出了异常,因为MySql查询顺序混乱。因此,我决定按顺序运行查询,这样后续查询就不会失败。我在这里找到了一个解决方案。https://michaelscodingspot.com/c-job-queues/ -
public class job_queue
{
private ConcurrentQueue<Action> _jobs = new ConcurrentQueue<Action>();
private bool _delegateQueuedOrRunning = false;
public void Enqueue(Action job)
{
lock (_jobs)
{
_jobs.Enqueue(job);
if (!_delegateQueuedOrRunning)
{
_delegateQueuedOrRunning = true;
ThreadPool.UnsafeQueueUserWorkItem(ProcessQueuedItems, null);
}
}
}
private void ProcessQueuedItems(object ignored)
{
while (true)
{
Action item;
lock (_jobs)
{
if (_jobs.Count == 0)
{
_delegateQueuedOrRunning = false;
break;
}
_jobs.TryDequeue(out item);
}
try
{
//do job
item();
}
catch
{
ThreadPool.UnsafeQueueUserWorkItem(ProcessQueuedItems, null);
throw;
}
}
}
}这是一个在队列中一个接一个地运行方法的类。并将包含Mysql查询的方法添加到job_queue by。
var mysql_tasks= new job_queue();
mysql_tasks.Enqueue(() => { Your_MYSQL_METHOD_HERE(); });发布于 2011-11-30 02:02:33
我猜您使用的是InnoDb (它允许您进行并发写入)。MyISAM只有表级锁定,因此将对写入进行排队。
我推荐一种类似于ruakh的方法,但是您可以在数据库中使用一个表来管理锁定。该表的名称类似于lock_control
就在您尝试对表进行大容量插入之前,您在这个lock_control表上请求了一个LOCK TABLES lock_control WRITE。如果您被授予了锁,则继续批量写入,然后释放锁。如果表被另一个线程写锁定,那么LOCK TABLES命令将阻塞,直到释放锁为止。
您可以使用直接插入到的表来执行此锁定,但我相信在您持有锁的同时,也不会有其他线程能够读取该表。
在数据库而不是文件系统中进行这种锁定的优点是,您可以从多个客户端机器插入数据,而且在MySQL中处理所有的锁定/插入感觉会更简单一些。
发布于 2011-11-30 01:57:07
创建一个Bulk insert服务/类,让客户端在其中抛出数据。
它一次只做一个。如果您需要,消息返回完成。
你不想把你的数据库阻塞到一个线程上,这会杀死其他所有的东西。
https://stackoverflow.com/questions/8315327
复制相似问题