关于逻辑/算法的想法以及如何防止对SqlServer的线程写入中的竞争
我有以下逻辑:
public void InQueueTable(DataTable Table) { int incomingRows = Table.Rows.Count; if (incomingRows >= RowsThreshold) { // asyncWriteRows(Table) return; } if ((RowsInMemory + incomingRows) >= RowsThreshold) { // copy and clear internal table // asyncWriteRows(copyTable) } internalTable.Merge(Table); }
这个算法有一个问题:
但是如果??? 假设第二个线程旋转并调用asyncWriteRows(xxxTable); 另外,拥有异步方法的每个线程都将写入SqlServer中的同一个表: SqlServer是否将这种multithreading写入function处理到同一个表中?
跟进
根据Greg D的建议:
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString, sqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.UseInternalTransaction)) { // perform bulkcopy }
无论如何,我仍然有发信号通知asyncWriteRows(copyTable)的问题。 该算法需要确定是否需要继续复制internalTable,clear internalTable和asyncWriteRows(copyTable)。 我认为我需要做的是将internalTable.Copy()
调用移动到它自己的方法:
private DataTable CopyTable (DataTable srcTable) { lock (key) { return srcTable.Copy(); } }
…然后对InQueue方法进行以下更改:
public void InQueueTable(DataTable Table) { int incomingRows = Table.Rows.Count; if (incomingRows >= RowsThreshold) { // asyncWriteRows(Table) return; } if ((RowsInMemory + incomingRows) >= RowsThreshold) { // copy and clear internal table // asyncWriteRows(CopyTable(Table)) } internalTable.Merge(Table); }
…最后,添加一个回调方法:
private void WriteCallback(Object iaSyncResult) { int rowCount = (int)iaSyncResult.AsyncState; if (RowsInMemory >= rowCount) { asyncWriteRows(CopyTable(internalTable)); } }
这就是我所确定的解决方案。 任何反馈?
有什么理由不能使用交易吗?
我现在承认我不是这个领域的专家。
使用事务和游标,如果操作很大,您将获得锁定升级。 例如,您的操作将开始锁定一行,然后是一个页面,然后是表格,如果需要,则阻止其他操作运行。 我认为SQL Server只是将这些被阻止的操作排队等待锁定被释放的白痴,但它只是返回错误而且由API程序员继续重试(如果我错了,有人会纠正我,或者如果它在更高版本中修复)。 如果您很乐意阅读可能会复制的旧数据,就像我们一样,我们更改了隔离模式以不必要地停止服务器阻塞操作。 ALTER DATABASE [dbname] SET READ_COMMITTED_SNAPSHOT ON;
您也可以更改插入语句以使用NOLOCK。 但请仔细阅读。
上述就是C#学习教程:关于逻辑/算法的想法以及如何防止对SqlServer的线程写入中的竞争分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/983153.html