C# 数据库写入Sql Bulk索引损坏异常问题
System.InvalidOperationException: DataTable internal index is corrupted: '4'
这几天发现数据库写入时报了这样的一个异常出来,之前从未出现过的,网上搜索了一下,多数是提到4个原因:
引用自:https://stackoverflow.com/questions/450675/datatable-internal-index-is-corrupted
Here are 4 reasons that I know how DataTable internal index is corrupted: '5' happens. 1) Changing values during DataView.ListChanged event. This is not supported. Look at the callstack and if you see DataView.OnListChanged and you are changing a DataRow/Set/Table, then index corruption will likely happen (i.e. thrown from DataRow.EndEdit) Short description of the problem: the internal indexes getting notified of the edits out-of-order. Workaround - use the DataTable.RowChanged event instead of the DataView.ListChanged. 2) There is still an unfixed bug when merging data into an existing DataRow that starts in the Added or Deleted state and ends in the Modified row state. DataAdapter.Fill, DataSet.Load, DataTable.Load when LoadOption.PreserveChanges. DataSet.Merge, DataTable.Merge deleted rows. DataSet.Merge(DataRow[]) for added rows. Short description of the problem: The DataTable tells the DataView to “add” instead of “change”, resulting in index corruption. 3) multi-threading The DataSet/DataTable and any connected objects are not thread safe. Make sure you lock all the appropriate objects. 4) When the DataColumn.DataType is a reference type and the values are being changed instead of being treated as read only. Example: DataColumn.DataType is byte[] and the column sorted. If the values in the byte array are changed instead of assigning a new byte array to the DataRow, the internal index doesn’t know about the change and becomes corrupt. This is data being changed without the internal index being notified.
因为我的代码用了多线程,猜测可能是由于这个原因,但是通过写测试代码测试,1000个线程不加锁来写,也没有这样问题存在。
折磨了几天后,又仔细看了下异常信息,用再接近报错代码的地方的信息搜索了下
at System.Data.RBTree`1.GetNewNode(K key) at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Boolean suppressEnsurePropertyChanged, Int32 position, Boolean fireEvent, Exception& deferredException) at System.Data.DataTable.InsertRow(DataRow row, Int64 proposedID, Int32 pos, Boolean fireEvent)
发面,按这个搜索的结果,就是和内存相关了,OutOfMemoryException,于是运行程序看了下内存,终于发现问题了,跑到高峰时,内存暴满了。
http://www.databaseforum.info/1/1/ec1879c1a0b65ca3.html
瀑汗啊!! 原来是内存崩溃造成的索引损坏!