web-dev-qa-db-ja.com

ORA-08177:このトランザクションのアクセスをシリアル化できません

ORA-08177例外をスローするADO.NETを使用した非常に単純なコードがあります。これの何が悪いのかわかりません。 Oracle32ビットクライアントがインストールされているWindowsVistaマシンでこれを試しています。 VisualStudioのコンパイルオプションはx86プラットフォームに設定されています。

Dim connection As OracleConnection = Nothing
Dim transaction As OracleTransaction = Nothing

Try
    connection = New OracleConnection("Data Source=ora10;User Id=userid;Password=passwd;")
    connection.Open()

    transaction = connection.BeginTransaction(IsolationLevel.Serializable)

    Dim inputStream As New System.IO.FileStream("Dummy.xls", IO.FileMode.Open)
    Dim fileLength As Integer = CType(inputStream.Length, Integer)
    Dim input(fileLength) As Byte

    Try
        inputStream.Read(input, 0, fileLength)
    Finally
        If inputStream IsNot Nothing Then inputStream.Close()
    End Try

    Dim deleteSql As String = "DELETE FROM TABLE1 WHERE Version = 'v1' "

    Dim cmd As New OracleCommand(deleteSql, connection, transaction)
    cmd.ExecuteNonQuery()

    Dim insertQuery As String = "INSERT INTO TABLE1 (VERSION, DATA) VALUES (:VERSION, :DATA) "
    Dim insertCmd As OracleCommand = New OracleCommand(insertQuery, connection, transaction)
    insertCmd.Parameters.Clear()
    insertCmd.CommandType = Data.CommandType.Text
    insertCmd.Parameters.AddWithValue(":VERSION", "v1")
    insertCmd.Parameters.AddWithValue(":DATA", input)

    insertCmd.ExecuteNonQuery()
    transaction.Commit()

Catch
    If transaction IsNot Nothing Then transaction.Rollback()
    Throw
Finally
    If transaction IsNot Nothing Then transaction.Dispose()
    If connection IsNot Nothing AndAlso connection.State <> ConnectionState.Closed Then connection.Close()
End Try

注意すべき重要なこと:(それらが接続されているかどうかはわかりません)が、マシンから最新のWindows Updateをアンインストールしても、この問題は発生しません。

誰かがこれに直面したか、ここで何が起こっているかについて何か手がかりがありますか?

編集:-

この問題が発生するのは、問題のblob列タイプがある場合のみであることがわかりました。単純な列の場合は正常に機能します。

その他の詳細(違いがあるかどうか不明)

私は64ビットのWindowsVistaビジネスマシンで作業しています。 Windows Vista用に32ビットのOracleクライアントをインストールしました(64ビットのOracleクライアントはVistaでは動作しないため)。 Visual Studioでx86(32ビット環境)用にプロジェクトをコンパイルしています。そして、これはコンソールアプリケーションであり、現時点では他の誰もデータベースにアクセスしていないことを私は知っています。したがって、複数のトランザクションが存在することはできません。

また、最新のWindows Updateをアンインストールしても、この問題は発生しません。 (KB963027、KB967190、KB959426、KB960225、KB960803、KB952004、KB956572、KB958687、KB958690、KB958481、KB958483、KB943729)

15
MOZILLA

同じテーブルをROLLBACKにロックする他のトランザクションを待機するシリアル化可能なトランザクションを使用しています。

この他のトランザクションがロールバックせずにコミットする場合、このエラーが発生します。

シナリオは次のようです。

  1. Aliceは、DELETE FROM TABLE1 WHERE Version = 'v1'を呼び出すブラウザセッションを開きます

    • Bobは、Aliceが実行した後、彼女がコミットする前にDELETE FROM TABLE1 WHERE Version = 'v1'を呼び出すセッションを開きます。

    BobVersion = 'v1'で行をロックしたため、Aliceのトランザクションは待機します

    • Aliceはトランザクションをコミットします

    • BobのトランザクションはCannot serialize accessで失敗します

これを回避するには、TRANSACTION ISOLATION LEVELREAD COMMITTEDに設定します。

transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)

この場合、Bobのトランザクションは、Aliceのトランザクションがコミットされた後にBobのトランザクションが開始されたかのように、Aliceが変更をコミットした後に再発行されます。

更新

接続の痕跡を投稿していただけませんか?

これを行うには、接続直後に次のコマンドを発行します。

(New OracleCommand("ALTER SESSION SET SQL_TRACE=TRUE", connection, transaction)).ExecuteNonQuery();

、次に$Oracle_HOME\admin\udumpで新しい*.trcファイルを探します

24
Quassnoi