C#多线程去操作数据库

十八道胡同 2013-10-16 10:55:36
我现在的功能是从一个List表里面查询一段时间的记录,分析记录,分析结果插入Exception表里面,全部处理完之后新增处理记录(查询起止时间)到record表里面。

查询记录应该可以是并行的,他是处理每辆车的出入口信息,而后在分析他们,把异常数据插入Exception表。
我现在是同步进行的,无法充分发挥服务器的优势(内存32G),测试时我本地本本4G内存和cpu使用率一直很底,想请问下数据库强人们,你们有什么好的办法吗?

另我用的是VS2010。
...全文
968 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
十八道胡同 2013-10-18
  • 打赏
  • 举报
回复
引用 17 楼 libinguest 的回复:
是自己来开线程 ?是不是用线程池好些? 线程是并行的,但是如果你不同的线程用的是一个数据库操作对象,可以说就没有起作用。 用多线程操作数据库查询时,建议引用脏读脏写。 最重要的还是首先确定整个执行过程用时过长是什么地方,再进行优化。
是都要插入同一个数据库表的,你的意思就是不起作用了?因为insert之前有一段计算的过程,我以为这个计算的过程可以利用数据库自己的锁机制让别的线程进行inset。
十八道胡同 2013-10-18
  • 打赏
  • 举报
回复
引用 18 楼 libinguest 的回复:
我的是windows service的,我没有设置他是STA的,难道window service不能多线程? 能用异步的地方,不建议用线程。
你这里异步的意思是 Parallel?
风之影子 2013-10-18
  • 打赏
  • 举报
回复
我的是windows service的,我没有设置他是STA的,难道window service不能多线程?


能用异步的地方,不建议用线程。

风之影子 2013-10-18
  • 打赏
  • 举报
回复
是自己来开线程 ?是不是用线程池好些?

线程是并行的,但是如果你不同的线程用的是一个数据库操作对象,可以说就没有起作用。

用多线程操作数据库查询时,建议引用脏读脏写。

最重要的还是首先确定整个执行过程用时过长是什么地方,再进行优化。

十八道胡同 2013-10-18
  • 打赏
  • 举报
回复
引用 2 楼 bdmh 的回复:
其实就是分几个线程,每个线程负责处理一个范围的记录,就像分页一样,每个线程负责一页,不过线程不要太多,视服务器的cpu数量而定,否则效率只会降低
我用多线程的时候碰到个
不支持一个 STA 线程上针对多个句柄的 WaitAll。
我的是windows service的,我没有设置他是STA的,难道window service不能多线程? 我在我的方法上加 [MTAThread]也不行。 在main上加 [MTAThread]也不行。
rtdb 2013-10-17
  • 打赏
  • 举报
回复
引用 11 楼 LCL_data 的回复:
[quote=引用 10 楼 rtdb 的回复:] 线程池肯定是没必要的。 其实简单改造一下, 让主程序接收命令行参数:查询时间范围 就可以变成多进程模式进行试验了。 然后你写个小程序,依次启动多个主程序,给以不同的时间范围就可以了。
谢谢回复。 顺序调用的多进程 也是串行的吧?[/quote] Process.Start()即可,此方法启动进程后立刻返回,不等待进程结束。
十八道胡同 2013-10-17
  • 打赏
  • 举报
回复
引用 13 楼 hdhai9451 的回复:
SQL Server通过在锁资源上使用不同类型的锁来隔离事务。为了开发安全的事务,定义事务内容以及应在何种情况下回滚至关重要,定义如何以及在多长时间内在事务中保持锁定也同等重要。这由隔离级别决定。应用不同的隔离级别,SQL Server赋予开发者一种能力,让他们为每一个单独事务定义与其他事务的隔离程度。事务隔离级别的定义如下: •是否在读数据的时候使用锁 •读锁持续多长时间 •在读数据的时候使用何种类型的锁 •读操作希望读已经被其他事务排他锁住的数据时,怎么办?在这种情况下,SQL Server可以: ◦一直等到其他事务释放锁 ◦读没有提交的数据 ◦读数据最后提交后的版本 ANSI 99定义了4种事务隔离级别,SQL Server 2005能够完全支持这些级别: •未提交读 在读数据时不会检查或使用任何锁。因此,在这种隔离级别中可能读取到没有提交的数据。 •已提交读 只读取提交的数据并等待其他事务释放排他锁。读数据的共享锁在读操作完成后立即释放。已提交读是SQL Server的默认隔离级别。 •可重复读 像已提交读级别那样读数据,但会保持共享锁直到事务结束。 •可序列化 工作方式类似于可重复读。但它不仅会锁定受影响的数据,还会锁定这个范围。这就阻止了新数据插入查询所涉及的范围,这种情况可以导致幻像读。 此外,SQL Server还有两种使用行版本控制来读取数据的事务级别(本章后文将详细检验这些隔离级别)。行版本控制允许一个事务在数据排他锁定后读取数据的最后提交版本。由于不必等待到锁释放就可进行读操作,因此查询性能得以大大增强。这两种隔离级别如下: •已提交读快照 它是一种提交读级别的新实现。不像一般的提交读级别,SQL Server会读取最后提交的版本并因此不必在进行读操作时等待直到锁被释放。这个级别可以替代提交读级别。 •快照 这种隔离使用行版本来提供事务级别的读取一致性。这意味着在一个事务中,由于读一致性可以通过行版本控制实现,因此同样的数据总是可以像在可序列化级别上一样被读取而不必为防止来自其他事务的更改而被锁定。 无论定义什么隔离级别,对数据的更改总是通过排他锁来锁定并直到事务结束时才释放。 很多情况下,定义正确的隔离级别并不是一个简单的决定。作为一种通用的规则,要选择在尽可能短的时间内锁住最少数据,但同时依然可以为事务提供它所需的安全程度的隔离级别 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED --未提交读 SET TRANSACTION ISOLATION LEVEL READ COMMITTED --已提交读 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ --获取一致的可重复读操作 SET TRANSACTION ISOLATION LEVEL SNAPSHOT --已提交读快照级 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE --系列化级别 更多参加: http://blog.csdn.net/hdhai9451/article/details/11028589
谢谢回复。我用的是db2
CGabriel 2013-10-16
  • 打赏
  • 举报
回复
程序的工作负荷非常低,逻辑简单。。 单线程同步可能才是最快的,因为开线程也是需要开销的。。搞不好得不偿失。。
QuickPai 2013-10-16
  • 打赏
  • 举报
回复
引用
引用 2 楼 bdmh 的回复:
其实就是分几个线程,每个线程负责处理一个范围的记录,就像分页一样,每个线程负责一页,不过线程不要太多,视服务器的cpu数量而定,否则效率只会降低

是自己来开线程 ?是不是用线程池好些?

自己试一下不就知道了
十八道胡同 2013-10-16
  • 打赏
  • 举报
回复
引用 2 楼 bdmh 的回复:
其实就是分几个线程,每个线程负责处理一个范围的记录,就像分页一样,每个线程负责一页,不过线程不要太多,视服务器的cpu数量而定,否则效率只会降低
是自己来开线程 ?是不是用线程池好些?
sj490790083 2013-10-16
  • 打赏
  • 举报
回复
用Parallel.Foreach()遍历数据并执行操作试试
十八道胡同 2013-10-16
  • 打赏
  • 举报
回复
引用 2 楼 bdmh 的回复:
其实就是分几个线程,每个线程负责处理一个范围的记录,就像分页一样,每个线程负责一页,不过线程不要太多,视服务器的cpu数量而定,否则效率只会降低
是cpu的核数的数量而定? 是核数*2 较为合适?
bdmh 2013-10-16
  • 打赏
  • 举报
回复
其实就是分几个线程,每个线程负责处理一个范围的记录,就像分页一样,每个线程负责一页,不过线程不要太多,视服务器的cpu数量而定,否则效率只会降低
十八道胡同 2013-10-16
  • 打赏
  • 举报
回复
list表是查询,并行应该是可以的。 Exception表是插入,并行也应该是可以的,做好修改锁就好。 Record表是最后插入的,只有一条记录。串行就可以的。 我的数据库是db2.
Andy__Huang 2013-10-16
  • 打赏
  • 举报
回复
SQL Server通过在锁资源上使用不同类型的锁来隔离事务。为了开发安全的事务,定义事务内容以及应在何种情况下回滚至关重要,定义如何以及在多长时间内在事务中保持锁定也同等重要。这由隔离级别决定。应用不同的隔离级别,SQL Server赋予开发者一种能力,让他们为每一个单独事务定义与其他事务的隔离程度。事务隔离级别的定义如下: •是否在读数据的时候使用锁 •读锁持续多长时间 •在读数据的时候使用何种类型的锁 •读操作希望读已经被其他事务排他锁住的数据时,怎么办?在这种情况下,SQL Server可以: ◦一直等到其他事务释放锁 ◦读没有提交的数据 ◦读数据最后提交后的版本 ANSI 99定义了4种事务隔离级别,SQL Server 2005能够完全支持这些级别: •未提交读 在读数据时不会检查或使用任何锁。因此,在这种隔离级别中可能读取到没有提交的数据。 •已提交读 只读取提交的数据并等待其他事务释放排他锁。读数据的共享锁在读操作完成后立即释放。已提交读是SQL Server的默认隔离级别。 •可重复读 像已提交读级别那样读数据,但会保持共享锁直到事务结束。 •可序列化 工作方式类似于可重复读。但它不仅会锁定受影响的数据,还会锁定这个范围。这就阻止了新数据插入查询所涉及的范围,这种情况可以导致幻像读。 此外,SQL Server还有两种使用行版本控制来读取数据的事务级别(本章后文将详细检验这些隔离级别)。行版本控制允许一个事务在数据排他锁定后读取数据的最后提交版本。由于不必等待到锁释放就可进行读操作,因此查询性能得以大大增强。这两种隔离级别如下: •已提交读快照 它是一种提交读级别的新实现。不像一般的提交读级别,SQL Server会读取最后提交的版本并因此不必在进行读操作时等待直到锁被释放。这个级别可以替代提交读级别。 •快照 这种隔离使用行版本来提供事务级别的读取一致性。这意味着在一个事务中,由于读一致性可以通过行版本控制实现,因此同样的数据总是可以像在可序列化级别上一样被读取而不必为防止来自其他事务的更改而被锁定。 无论定义什么隔离级别,对数据的更改总是通过排他锁来锁定并直到事务结束时才释放。 很多情况下,定义正确的隔离级别并不是一个简单的决定。作为一种通用的规则,要选择在尽可能短的时间内锁住最少数据,但同时依然可以为事务提供它所需的安全程度的隔离级别 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED --未提交读 SET TRANSACTION ISOLATION LEVEL READ COMMITTED --已提交读 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ --获取一致的可重复读操作 SET TRANSACTION ISOLATION LEVEL SNAPSHOT --已提交读快照级 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE --系列化级别 更多参加: http://blog.csdn.net/hdhai9451/article/details/11028589
Andy__Huang 2013-10-16
  • 打赏
  • 举报
回复
使用事务隔离。
十八道胡同 2013-10-16
  • 打赏
  • 举报
回复
引用 10 楼 rtdb 的回复:
线程池肯定是没必要的。 其实简单改造一下, 让主程序接收命令行参数:查询时间范围 就可以变成多进程模式进行试验了。 然后你写个小程序,依次启动多个主程序,给以不同的时间范围就可以了。
谢谢回复。 顺序调用的多进程 也是串行的吧?
rtdb 2013-10-16
  • 打赏
  • 举报
回复
线程池肯定是没必要的。 其实简单改造一下, 让主程序接收命令行参数:查询时间范围 就可以变成多进程模式进行试验了。 然后你写个小程序,依次启动多个主程序,给以不同的时间范围就可以了。
w2579194474 2013-10-16
  • 打赏
  • 举报
回复
帮顶,看回复…学习。
showjim 2013-10-16
  • 打赏
  • 举报
回复
读数据库操作,如果不是复杂的查询语言(IO多CPU少),一般情况不需要多线程。 分析记录,如果是CPU密集型的,根据核心数量并发线程。 异常数据可以用一个单独的线程一批一批的导入。

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧