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)
同じテーブルをROLLBACK
にロックする他のトランザクションを待機するシリアル化可能なトランザクションを使用しています。
この他のトランザクションがロールバックせずにコミットする場合、このエラーが発生します。
シナリオは次のようです。
Alice
は、DELETE FROM TABLE1 WHERE Version = 'v1'
を呼び出すブラウザセッションを開きます
Bob
は、Alice
が実行した後、彼女がコミットする前にDELETE FROM TABLE1 WHERE Version = 'v1'
を呼び出すセッションを開きます。Bob
がVersion = 'v1'
で行をロックしたため、Alice
のトランザクションは待機します
Alice
はトランザクションをコミットします
Bob
のトランザクションはCannot serialize access
で失敗します
これを回避するには、TRANSACTION ISOLATION LEVEL
をREAD 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
ファイルを探します