0

我正在开发的停车场数据库系统的一部分涉及将数据从车牌读取相机加载到数据库表中。使用 .net 连接器中的 Bulk Loader 对象(用于试验单行和多行文件),我设法做到了,但是会弹出一个定期但间歇性的错误,我希望这里有人可以帮我找出问题所在并提供解决方案

我正在使用一对 filesystemwatcher 对象来监视摄像机(入口和出口)输出其 CSV 数据的位置。在“文件创建”事件中,触发另一个子程序,然后将文件的内容加载到数据库中。下面列出了此子程序的代码:

Public Sub sqlloaddata_in(ByVal sqlfilepath As String)

        loaddatainsqlconn = New MySqlConnection
        loaddatainsqlconn.ConnectionString = "Server=localhost;user id=root;password=W1nd0ws;database=hystest"

        Try
            'instanciate a mysqlbulkloader, feed in the parameters
            Dim sqlbulkin As New MySqlBulkLoader(loaddatainsqlconn)
            Dim insertedin As Long
            sqlbulkin.TableName = "hystest.tblin_dupebuffer"
            sqlbulkin.FieldTerminator = ","
            sqlbulkin.LineTerminator = "\n"
            sqlbulkin.FileName = sqlfilepath
            'sqlbulkin.ConflictOption = MySqlBulkLoaderConflictOption.Ignore
            sqlbulkin.NumberOfLinesToSkip = 1
            'load the data into the database. return the number of rows inserted into the variable
            insertedin = sqlbulkin.Load
            Debug.Print(insertedin & " rows inserted.")

            ' refreshdatagrid_in()
            'close and get rid of the connection
            loaddatainsqlconn.Close()
            loaddatainsqlconn.Dispose()
            'transferdata_in()
        Catch ex As MySqlException
            'if bad stuff happens, do this
            'MessageBox.Show("Database Error: " & ex.Message & vbCrLf & ex.InnerException.Message)
            'Debug.Print(ex.Message & ex.InnerException.Message & ex.InnerException.InnerException.Message)
            Debug.Print(ex.ToString)
            'Debug.Print("Retrying insert")
            'Try
            '    sqlloaddata_in(sqlfilepath)
            'Catch ex2 As Exception

            'End Try
        End Try
        'dedupe_in()
    End Sub

每次创建新文件时都会运行此子程序(相机每 10 秒输出一个文件),但是在运行时会产生以下错误(取自调试窗口):

1 rows inserted.
A first chance exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
MySql.Data.MySqlClient.MySqlException (0x80004005): Fatal error encountered during command execution. ---> MySql.Data.MySqlClient.MySqlException (0x80004005): Fatal error encountered attempting to read the resultset. ---> MySql.Data.MySqlClient.MySqlException (0x80004005): Error during LOAD DATA LOCAL INFILE ---> System.IO.IOException: The process cannot access the file 'C:\HYS Database\Raw\IN\INLIST_HYS,HN03KTG,1970-01-01,03-36-01-582.CSV' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
   at MySql.Data.MySqlClient.NativeDriver.SendFileToServer(String filename)
   at MySql.Data.MySqlClient.NativeDriver.SendFileToServer(String filename)
   at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
   at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
   at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
   at MySql.Data.MySqlClient.MySqlBulkLoader.Load()
   at SmartPark_Data_Loader.mysql.sqlloaddata_in(String sqlfilepath) in C:\Users\<name>\Dropbox\Visual Studio 2010\Projects\SmartPark Data Loader\SmartPark Data Loader\mysql.vb:line 201
1 rows inserted.
1 rows inserted.
1 rows inserted.
1 rows inserted.
1 rows inserted.
1 rows inserted.

在上面的示例中,一个文件被成功插入,然后在第二个文件中弹出错误。这大约需要一分钟时间,在此期间,已经创建了几个其他文件,创建了要处理的事件积压,然后正确插入。

这种情况经常发生,我不确定为什么。调试窗口的最终布局在错误和文件事件的结果积压之间交替。

我该怎么办?

4

1 回答 1

0

我认为 Steven Doggart 先生注意到了相应的错误信息:

 C:\HYS Database\Raw\IN\INLIST_HYS,HN03KTG,1970-01-01,03-36-01-582.CSV

当 MySQL 客户端代码读取该文件时,该文件似乎无法访问。

假设这是正确的文件名,只有您知道,那么您遇到了文件系统观察程序的一个非常常见的问题。当目录改变时,他们会触发他们的事件。

所以,在程序写入文件的那一刻之间有一个时间窗口

  1. 创建文件,并且
  2. 写完并关闭它。

如果您的程序尝试在该时间窗口内打开文件,则可能会导致此错误。

这是解决此问题的一种方法。让您的程序在循环中尝试打开文件进行读取(然后立即关闭它),然后再将文件名传递给批量加载程序。如果您的打开尝试失败(抛出异常),请休眠十几毫秒左右,然后重试。不要让这个循环无限:尝试十次左右后放弃。您不希望您的程序在执行此操作时挂起。

于 2013-08-30T12:59:40.270 回答