ORA-08177: невозможно сериализовать доступ для этой транзакции - PullRequest
13 голосов
/ 24 апреля 2009

У меня очень простой код с использованием 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 с моего компьютера.

Кто-нибудь сталкивался с этим или имеет какое-либо представление о том, что здесь происходит?

Edit: -

У меня есть некоторый прогресс, когда я обнаружил, что эта проблема возникает только тогда, когда у нас есть вопрос типа столбца BLOB. для простых столбцов работает нормально.

Другие детали (не уверен, если это имеет значение)

Я работаю на 64-битной Windows Vista. Я установил 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 Ответ

21 голосов
/ 24 апреля 2009

Вы используете сериализуемую транзакцию, которая ожидает какой-либо другой транзакции, блокирующей ту же таблицу на ROLLBACK.

Если эта другая транзакция не откатывается, а фиксируется, вы получите эту ошибку.

Сценарий выглядит следующим образом:

  1. 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 файл

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...