1

VS 2010を使用して2つのデータベース(SQLExpressとSQLCompact Edition)を同期しています。プログラムを最初に実行したときに正常に動作します。ただし、コードが数回実行された場合、SQLコマンドの「タイムアウトが期限切れ」例外が発生しました。エラーメッセージは次のとおりです。

タイムアウトが期限切れになりました。操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。

以下は、 ClientInsertServerInsertの競合を処理するための私のコードです。(編集:このMSDNの記事によると、これはクライアントとサーバーの両方が同じ主キー値を持つ行を挿入することと関係があります。これにより、主キー違反が発生します。)

    Dim conflictTableName As String = e.TableMetadata.TableName.ToString
    Dim serverConflictDT, clientConflictDT As DataTable
    Dim clientConflictID As Int16
    Dim new_ID As Int16
    Dim SqlCon As New SqlConnection
    clientConflictDT = e.Conflict.ClientChange
    serverConflictDT = e.Conflict.ServerChange

    If e.Conflict.ConflictType = ConflictType.ClientInsertServerInsert Then
        SqlCon = New SqlConnection(STR_SQL_CON)

        Using SqlCon
            If SqlCon.State = ConnectionState.Closed Then SqlCon.Open()
            MsgBox(SqlCon.PacketSize.ToString & vbNewLine & conflictTableName.ToString)
            Dim sqlStr = "SELECT CASE WHEN MAX(ID) IS NULL THEN 0 ELSE MAX(ID)+1 END               FROM " & conflictTableName

            Dim sqlcmd As New SqlCommand(sqlStr, SqlCon)
            sqlcmd.CommandTimeout = 2

            new_ID = sqlcmd.ExecuteScalar  '<- This is the line where the Exception occurred

            clientConflictID = clientConflictDT.Rows(0)(0)

            MsgBox(new_ID.ToString & conflictTableName.ToString)

            Try
                Using SqlCeCon As New SqlCeConnection(STR_SQLCE_CON)
                    If SqlCeCon.State = ConnectionState.Closed Then SqlCeCon.Open()

                    Dim sqlCeCmd As New SqlCeCommand
                    Dim sqlCeStr = Nothing

                    sqlCeStr = "SELECT CASE WHEN MAX(ID) IS NULL THEN 0 ELSE MAX(ID)+1 END FROM " & conflictTableName
                    sqlCeCmd = New SqlCeCommand(sqlCeStr, SqlCeCon)
                    If new_ID < sqlCeCmd.ExecuteScalar Then
                        new_ID = sqlCeCmd.ExecuteScalar
                    End If

                    sqlCeStr = "UPDATE " & conflictTableName & " SET id=" & new_ID & " WHERE id=" & clientConflictID
                    sqlCeCmd.CommandText = sqlCeStr
                    sqlCeCmd.ExecuteNonQuery()
                End Using
            Catch ex As Exception

            Finally

            End Try

        End Using


    End If

前もって感謝します

4

1 に答える 1

2

データベースのロックが原因だったと思います。から SQL SELECT ステートメントを変更した後

"SELECT CASE WHEN MAX(ID) IS NULL THEN 0 ELSE MAX(ID)+1 END FROM " & conflictTableName 

"SELECT CASE WHEN MAX(ID) IS NULL THEN 0 ELSE MAX(ID)+1 END FROM " & conflictTableName & " WITH (NOLOCK)"

その後、問題は解決しました。

とにかく、すべてのコメントをありがとう:-)

于 2012-06-05T02:55:28.737 に答える