ORA-08177: невозможно сериализовать доступ для этой транзакции
У меня есть очень простой код с использованием ADO.NET, который выдает исключение ORA-08177. Я не уверен, что с этим не так. Я пытаюсь это на машине Windows Vista, на которой установлен 32-битный клиент Oracle. Мой вариант компиляции для Visual Studio установлен на платформе 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 с моей машины.
Кто-нибудь сталкивался с этим или имеет какое-либо представление о том, что здесь происходит?
Редактировать:-
У меня есть некоторый прогресс, когда я обнаружил, что эта проблема возникает только тогда, когда мы имеем дело с типом столбца blob. для простых столбцов работает нормально.
Другие детали (не уверен, если это имеет значение)
Я работаю на 64-битной Windows Vista Business Machine. Я установил 32-битный клиент Oracle для Windows Vista (так как 64-битный клиент Oracle не работает на Vista). Я собираю свой проект для x86 (32-битная среда) в Visual Studio. И это консольное приложение, и я знаю, что в данный момент никто больше не использует базу данных. поэтому не может быть несколько транзакций.
И я не вижу этой проблемы, если я удаляю последнее обновление Windows. (KB963027, KB967190, KB959426, KB960225, KB960803, KB952004, KB956572, KB958687, KB958690, KB958481, KB958483, KB943729)
1 ответ
Вы используете сериализуемую транзакцию, которая ожидает какой-либо другой транзакции, блокирующей ту же таблицу ROLLBACK
,
Если эта другая транзакция не откатывается, а фиксируется, вы получите эту ошибку.
Сценарий выглядит следующим образом:
Alice
открывает сеанс браузера, который вызываетDELETE FROM TABLE1 WHERE Version = 'v1'
Bob
открывает свою сессию, которая вызываетDELETE FROM TABLE1 WHERE Version = 'v1'
послеAlice
сделал это, но прежде чем она совершила.
Bob
транзакция ждет сAlice
заблокировал ряды сVersion = 'v1'
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
файл