Почему это обновление блокирует строку в Oracle 10? - PullRequest
2 голосов
/ 06 июля 2010

Вот код (с удаленным сервером / паролями и т. Д.)

  public int SetUploadedInESIDatabase(string ID)
        {
            using (var oOracleConn = new OracleConnection())
            {
                oOracleConn.ConnectionString =
                    @"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=<ip>)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=<dbname>)));User Id=<user>;Password=<password>;";
                var cmd =
                    new OracleCommand(
                        "UPDATE FOO_ACCESS SET PIMAGE ='-1' WHERE CODE= '" + ID + "'", oOracleConn);

                oOracleConn.Open();



                return  cmd.ExecuteNonQuery();

            }
        }

Эффект этого кода в том, что он никогда не выходит за пределы оператора return. Ошибка не возвращается (даже за одну ночь)

Я не эксперт по базам данных, но наш жесткий администратор БД говорит, что соединение было заблокировано (или, возможно, строка ...), он убил блокирующее соединение, но все же, когда я запускаю код, оно блокируется.

Я ошибаюсь (tm) в отношении запроса Oracle на обновление строки?

Я понимаю, что должен использовать параметризованный запрос, но у меня была проблема с этим, и мне нужны были простые вещи! Если я скопирую встроенную команду из cmd. с помощью отладчика и запустите его с помощью SQL Developer, затем он работает (хотя иногда он тоже блокируется)

Я могу выбрать из базы данных по желанию.

Я не уверен, является ли это нормальным явлением или чем-то, что связано с нашей средой, поэтому любая помощь с радостью принимается!

Ответы [ 9 ]

2 голосов
/ 06 июля 2010

Объединение ответов @ Tony's и @Panagiotis и расширение:

Где вы делаете ОБНОВЛЕНИЕ, выполненное в этом коде?Вы уверены, что это делается?

Может ли это быть вашим сценарием:

  1. Вы выполнили вышеупомянутое ОБНОВЛЕНИЕ, но никогда не фиксируете.изменения, так что вы попробуйте еще раз.Теперь он зависает.

Строки, на которые влияет UPDATE, заблокированы от дальнейших обновлений до их фиксации или отката.Если вы никогда не выполняете явную фиксацию или откат, последующие обновления будут зависать.

Если вы хотите избежать зависания в своем коде, выполните

SELECT... FOR UPDATE NOWAIT;

перед выполнением ОБНОВЛЕНИЯ.Если запись заблокирована, выбор вернет ошибку, которую вы можете перехватить и обработать.

Попросите своего администратора базы данных выполнить этот запрос (следует поблагодарить Тома Кайта):

select
      (select username from v$session where sid=a.sid) blocker,
       a.sid,
      ' is blocking ',
       (select username from v$session where sid=b.sid) blockee,
           b.sid
  from v$lock a join v$lock b on (a.id1 = b.id1 and a.id2 = b.id2)
 where a.block = 1
   and b.request > 0;

Чтобы просмотреть все блоки в очереди в сеансах.

1 голос
/ 06 июля 2010

Вы пытались указать режим изоляции, создав транзакцию, например

using(OracleTransaction transaction = oOracleConn.BeginTransaction(IsolationLevel.RepeatableRead)
{

cmd.Transaction = transaction

return  cmd.ExecuteNonQuery();
}
1 голос
/ 06 июля 2010

Мне интересно одно. Можете ли вы попробовать изменить оператор возврата так, чтобы он находился за пределами блока using?

т.е. вместо:

using (..snip...) {

  return  cmd.ExecuteNonQuery();
}

попробовать

int rv;
using () {

  rv = cmd.ExecuteNonQuery();
}
return rv;
1 голос
/ 06 июля 2010

Oracle заблокирует строку, если несколько писателей попытаются прикоснуться к ней одновременно. Какой-то другой код пытается изменить строку или таблицу одновременно? Возможно, вы выполнили инструкцию SELECT FOR UPDATE в другом открытом соединении?

1 голос
/ 06 июля 2010

Вы пытались открыть соединение перед созданием объекта команды?

1 голос
/ 06 июля 2010

Если один сеанс выдает это обновление и не фиксирует или не выполняет откат, строка блокируется этим сеансом до тех пор, пока это не произойдет (принятие или откат).Может ли это быть тем, что с тобой происходит?

1 голос
/ 06 июля 2010

Вы уверены, что параметр studentID действительно является идентификатором?Что делать, если это был искаженный бит SQL, который кто-то пытается внедрить ?

Вполне возможно, что некоторые неанизированные данные попали в studentID - и ваш запрос что-то делаеткроме того, что вы ожидаете.

Например, если studentID = "'; DROP ALL TABLES; --", у вас может быть проблема ...

Использование конкатенации строк в качестве средства для создания оператора SQL является небезопасной практикой - итот, который совершенно не нужен.Использовать параметры в командах SQL в .NET довольно просто, что делает SQL менее восприимчивым к атакам с использованием инъекций, а также повышает их производительность (уменьшая необходимость выполнения анализа операторов).

Вот пример, в котором используютсяпараметры:

var cmd = new OracleCommand( 
       "UPDATE FOO_ACCESS SET PIMAGE = '-1' WHERE CODE = :code", oracleConn );
cmd.Parametes.Add( ":code", studentID );

cmd.ExecuteNonQuery();

Помимо этого, вы можете исследовать причины плохой работы вашего запроса, используя таблицы V $ XXX в Oracle, чтобы изучить происходящее.Если вы считаете, что у вас есть блокировка, вы можете запросить таблицу v$lock, чтобы узнать, какие таблицы заблокированы какими сеансами.

1 голос
/ 06 июля 2010
  • Узнайте, что именно заблокировано (таблица, строка и т. Д.)

  • Можете ли вы выполнить оператор из sqlplus или sqldeveloper используя те же учетные данные?

  • Есть ли триггеры, прикрепленные к таблица FOO_ACCESS?

0 голосов
/ 06 июля 2010

Кажется, проблема была в том, что я не совсем понимал свои инструменты.

Я считаю, что SQL Developer создавал блокировку в какой-то момент, а затем, когда я запустил свое веб-приложение для обновления той же строки, оно блокировалось. В своем разочаровании и невежестве я принудительно закрыл SQL Developer, оставив блокировку в базе данных, и я не смог снять ее без полномочий супер-администратора.

Теперь, когда очистили блокировку и закрыли все работающие копии SQL Developer, код, как я его впервые опубликовал, теперь работает. (Уф!)

Спасибо за вашу помощь, особенно за идею SELECT FOR UPDATE, чтобы увидеть, будет ли отказано в моем обновлении, прежде чем я его выпущу:)

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