63474

Java DataBase Connectivity. Уровни изолированности транзакций

Лекция

Информатика, кибернетика и программирование

Есть несколько способов разрешения конфликтов между одновременно выполняющимися транзакциями. Пользователь может задать уровень изолированности, то есть уровень внимания, которое СУБД должна уделить при разрешении возможных конфликтов.

Русский

2014-06-20

84 KB

0 чел.

I. Java DataBase Connectivity                                                                                                    Лекция 9.

Уровни изолированности транзакций

Есть несколько способов разрешения конфликтов между одновременно выполняющимися транзакциями. Пользователь может задать уровень изолированности, то есть уровень внимания, которое СУБД должна уделить при разрешении возможных конфликтов. Например, что будет, если одна транзакция изменит какое-либо значение, а вторая транзакция прочитает его перед тем, как первая выполнит commit или rollback? Допустимо ли это, например, если это значение, будучи уже прочитанным второй транзакцией, окажется некорректным и будет откатано (rolled back) первой? Пользователь JDBC может указать СУБД на возможность чтения измененных значений до того, как выполнится commit («грязное чтение», «dirty reads»). Это делается так (con – это соединение с БД):

con.setTransactionIsolation (TRANSACTION_READ_UNCOMMITTED);

Чем выше уровень изолированности транзакций, тем больше внимания СУБД уделяет устранению конфликтов. Интерфейс Connection определяет пять таких уровней. Минимальный из них соответствует случаю, когда транзакции не поддерживаются вовсе, а максимальный – невозможности существования более одной транзакции в любой момент времени. Обычно, чем выше уровень изолированности, тем медленнее выполняется приложение (из-за избыточной блокировки и уменьшенной конкурентности пользователей). При выборе конкретного уровня изолированности разработчик должен найти золотую середину между потребностями в производительности и требованиями к целостности данных. Очевидно, что реально поддерживаемые уровни зависят от возможностей используемой СУБД.

При создании объекта Connection его уровень изолированности зависит от драйвера или БД. Пользователь может вызвать метод setIsolstionLevel, чтобы изменить уровень изолированности транзакций, и новое значение уровня будет установлено до конца сессии. Чтобы установить уровень изолированности только для одной транзакции, надо установить его перед выполнением транзакции и восстановить прежнее значение после ее завершения. Изменение уровня изолированности во время самой транзакции нежелательно, так как произойдет автоматический вызов commit, что повлечет за собой фиксацию изменений.

public int getTransactionIsolation ( ) throws SQLException

TRANSACTION_NONE

Транзакции не поддерживаются.

TRANSACTION_READ_COMMITTED

«Грязное чтение» предотвращается; разовые чтения и фантомные чтения могут происходить. Это уровень препятствует транзакциям от чтения строк с неподтвержденными изменениями в них.

TRANSACTION_READ_UNCOMMITTED

«Грязное чтение», разовое чтение и фантомное чтение может происходить. Этот уровень позволяет изменять строку с помощью одной транзакции и прочесть ее другой прежде, чем изменения в этой строке будут подтверждены («грязное чтение»). Если изменения будут отменены с помощью rollback ( ), вторая транзакция вернет неправильную строку.

TRANSACTION_REPEATABLE_READ

«Грязное чтение» и разовое чтение предотвращаются; фантомные чтения могут происходить. Этот уровень препятствует транзакции от чтения строки с неподтвержденным изменением в ней, он также предотвращает ситуацию, когда одна транзакция читает строку, а вторая транзакция изменяет ее, при этом первая транзакция перечитывая строку, получает разные значения каждый раз (разовое чтение).

TRANSACTION_SERIALIZABLE

«Грязное чтение», разовое чтение и фантомное чтение предотвращаются. Этот уровень включает предотвращения из TRANSACTION_REPEATABLE_READ, более того предотвращает ситуацию, когда одна транзакция читает все строки, которые удовлетворяют условию WHERE, а вторая транзакция вставляет строку, которая удовлетворяет тому же условию WHERE, и первая транзакция, перечитывая с тем же условием, получает дополнительную «фантомную» строку при втором чтении.

PreparedStatement

Интерфейс PreparedStatement наследует от Statement и отличается от последнего следующим:

  1.  Экземпляры PreparedStatementпомнятскомпилированые SQL-выражения. Именно поэтому они называются “prepared” ( “подготовленные” ).
  2.  SQL-выражения в PreparedStatement могут иметь один или более (IN) входной параметр. Входной параметр – это параметр, чье значение не указывается при создании SQL-выражения. Вместо него в выражении на месте каждого входного параметра ставится знак (“?”). Значение каждого вопросительного знака устанавливается методами sеtXXX перед выполнением запроса.

Поскольку объекты PreparedStatement прекомпилированы, исполнение этих запросов может происходить несколько быстрее, чем в объектах Statement. В результате SQL-выражения, которые исполняются часто, в целях улучшения производительности создают в виде объектов PreparedStatement. 

Оставаясь подклассом класса Statement, класс PreparedStatement наследует все функции от Statement. В дополнении к ним он добавляет методы установки входных параметров. Кроме того, три метода – execute, executeQuery и executeUpdate – модифицированы таким образом, что не имеют аргументов. Старые методы класса Statement ( которые принимают SQL-выражения в качестве единственного аргумента ) не должны использоваться в объекте PreparedStatement.

Создание объектов PreparedStatement

Следующий фрагмент кода, где con – это объект Connection , создает объект PreparedStatement, содержащий SQL-выражение с двумя параметрами:

PreparedStatement pstmt = con. prepareStatement  (

           “UPDATE table4 SET m = ? WHERE x = ?” );

Объект pstmt отныне содержит выражение UPDATE table4 SET m = ? WHERE x = ?” ), которое уже отослано в СУБД и подготовлено для выполнения.

Передача входных ( IN ) параметров  

Перед выполнением объекта PreparedStatement надо установить значения всех его параметров. Это делается с помощью методов setXXX, где XXX – это тип параметра. Например, если параметр имеет Java-тип long, используемый метод будет setLong. Первый аргумент методов setXXX – это порядковый номер параметра, а второй – значение, в которое надо его установить. Например, следующий код устанавливает первый параметр в значение 123456789, a второй – 100000000:

pstmt .steLong ( 1,123456789 );

pstmt .steLong ( 2,100000000 );

После установки параметра его можно использовать при многократном выполнении выражения до тех пор, пока он не очистится методом clearParameters.

В режиме соединения по умолчанию (разрешена автофиксация) – каждый запрос фиксируется или откатывается автоматически.

Один и тот же объект PreparedStatement может выполняться много раз, если нижестоящий драйвер или СУБД  будут сохранять выражение (statement) в открытом состоянии даже после того как произойдет фиксация. Иначе не имеет смысла пытаться улучшить производительность заменой на PreparedStatement.

Используя pstmt из предыдущего примера, следующий код устанавливает значение обоих параметров и выполняет pstmt 10 раз. Как уже было отмечено, БД не должна закрывать pstmt. В этом примере первый параметр устанавливается в “Hi” и остается неизменным. Второй параметр устанавливается в последовательные целые значения, начиная от 0 и заканчивая  9.

pstmt.setString (1, “Hi”);

for (int  i = 0; i < 10; i++)    {

         pstmt.setInt (2, i);

         int rowCount = pstmt.executeUpdate ( );

}

Совместимость типов данных входных параметров

ХХХ в названии методов setXXX – это тип данных Java. Неявно он же является и типом данных JDBC (SQL), так как драйвер отображает тип данных Java на соответствующий JDBC-тип передотсылкой JDBC-типа в БД. Следующий код устанавливает второй параметр объекта PreparedStatement pstmt в 44 с типом данных short:

pstmt.setShort (2, 44);

Драйвер отошлет 44 в БД в виде типа JDBC SMALLINT, который является стандартным для Java-типа short.

На программисте лежит ответственность за совместимость Java-типов входных параметров и ожидаемой базой данных соответствующих JDBC-типов. Рассмотрим случай, когда ожидается SMALLINT. Если используется метод setByte, то драйвер отошлет значение TINYINT в БД. Это вероятно, работать будет, так как многие БД преобразуют «похожие» типы данных друг в друга. Тем не менее, чтобы приложение могло работать как можно с большим количеством СУБД, лучше использовать Java-типы, которые в точности соответствуют ожидаемым JDBC-типам. Если ожидается JDBC-тип данных SMALLINT, то использование именно setShort вместо setByte сделает приложение более переносимым.

Использование объектов

Программист может явно задать конвертирование входных параметров в определенный JDBC-тип с помощью метода setObject. Этот тип может принимать третий аргумент, указывающий целевой JDBC-тип данных. Перед отправкой в БД драйвер преобразует Object в указанный JDBC-тип.

Если JDBC-тип не задан, то драйвер просто преобразует Object в его ближайший JDBC-эквивалент, а затем пошлет его в БД.  Это подобно использованию обычных методов setXXX; в обоих случаях драйвер отображает Java-типы в JDBC-типы данных перед отправкой значений в БД.

В случае использования метода setObject тип данных может быть неизвестен приложения на этапе его компиляции. Используя его, приложение может подавать на вход значения любых типов данных и преобразовывать их в ожидаемый базой данных JDBC-тип.

Отсылка значений NULL в качестве входного параметра

Метод setNull позволяет отсылать значения NULL в БД как входные параметры. Хотя JDBC-тип параметра все же можно задать явно.

JDBC-значение NULL будет отослано в БД также в том случае, если методу setXXX будет предано Java-значение null ( если метод принимает Java-объект в качестве аргумента ). Тем не менее, метод setObject может принимать значение null только в том случае, если задан JDBC-тип.

Отправка очень больших входных параметров

Методы setBytes и setString могут отсылать неограниченное количество данных. Правда, иногда программисту легче передавать большие значения в виде маленьких кусков. Это делается установкой входного параметра в значение Java-потока ввода ( input stream ). Когда выполняется выражение, JDBC-драйвер будет производить последовательные вызовы из этого потока ввода, считывая его содержимое и пересылая его в виде значения параметра.

JDBC предоставляет три метода установки входных параметров в поток ввода: setBinaryStream для потоков, содержащих обычные байты, setAsciiStream для потоков ASCII-символов и setUnicodeStream для потоков Unicode-символов. Эти методы, в отличие от остальных методов setXXX, принимают дополнительный аргумент, равный количеству передаваемых в потоке байтов. Этот аргумент необходим, так как некоторые СУБД требуют указания размера данных перед их отсылкой.

Следующий код иллюстрирует отсылку файла в виде входного параметра запроса:

java.io.File file = new java.io.File (“/tmp/data”);

int fileLength = file.length ( );

java.io.InputStream fin = new java.io.FileInputStream (file);

java.sql.PreparedStatement pstmt = con.preparedStatement ( );

           “UPDATE Table 5 SET stuff = ? WHERE index = 4”);

pstmt.setBinaryStream (1, fin, filelength);

pstmt.executeUpdate ( );

При выполнении запроса для доставки данных последовательно считывается поток ввода fin.

CallableStatement (вызываемый оператор)

Объект CallableStatement  предоставляет унифицированный способ вызова хранимых процедур в любой СУБД. Вызов процедуры осуществляется с помощью escape-синтаксиса в одной из двух форм: с результирующим параметром и без него. Результирующий параметр – это один из типов выходных (OUT) параметров, являющийся возвращаемым значением хранимой процедуры. Обе формы могут иметь переменное число аргументов на входе (параметры IN), выходе (параметры OUT) или входных и выходных параметров одновременно (INOUT-параметры). Вопросительный знак означает местоположение параметра.

Синтаксис вызова хранимой процедуры в JDBC показан ниже. Квадратные скобки означают, что-то, что находиться между ними, необязательно, и сами по себе не являются частью синтаксиса.

{ call имя_процедуры [ (?, ?, . . .) ] }

Синтаксис для процедуры, возвращающей результат:

{ ? = call имя_процедуры [ (?, ?, . . .) ] }

Синтаксис хранимой процедуры без параметров:

{ call имя_процедуры }

Обычно тот, кто использует объект CallableStatement, уже знает, что используемая СУБД поддерживает хранимые процедуры, и какие именно процедуры имеются в БД. Тем не менее, чтобы это выяснить, достаточно вызвать некоторые методы объекта DatabaseMetaData. Например, метод supportsStoredProcedures возвращает true, если СУБД поддерживает хранимые процедуры, а метод getProcedures возвращает описания доступных процедур.

CallableStatement наследует методы Statement общей для обработки SQL-запросов, а также методы PreparedStatement для обработки входных (IN) параметров. Все методы, объявленные в CallableStatement обрабатывают выходные (OUT) параметры следующим образом: указание JDBC-типов данных (т.е. SQL-типов) выходных параметров, извлечение из них значений или проверка их на NULL.

Создание объекта CallableStatement

Объекты CallableStatement создаются методом prepareCall объекта Connection. Приведем пример, который создает экземпляр CallableStatement, содержащий вызов хранимой процедуры getTestData с двумя аргументами и без возвращаемого параметра:

CallableStatement  cstmt = con.prepareCall ( “ {call  getTestData ( ?, ? ) } “ );

Какими именно параметрами ( IN, OUT или INOUT) являются знаки вопроса – зависит от самой хранимой процедуры getTestData.

IN- и OUT-параметры

Передача значений входных параметров объекта CallableStatement осуществляется с помощью методов setXXX, унаследованных от PreparedStatement. Типы передаваемых значений определяются тем, какой из методов setXXX используется ( setFloat для передачи значений float и т.п.).

JDBC-типы всех OUT-параметров хранимых процедур должны быть зарегистрированы перед их вызовом. Это необходимо, так как некоторым СУБД нужно передавать информацию о типах данных. Регистрация типов данных выходного параметра производится методом registerOutParameter. Только в этом случае после выполнения запроса методы getXXX класса CallableStatement смогут получить значения параметров. Необходимо использовать подходящий по типу данных Java метод getXXX в соответствии с зарегистрированными JDBC-типом параметра. Другими словами,  registerOutParameter используют JDBC-тип ( тот, который подходит к JDBC-типу возвращаемого из БД значения ), а getXXX преобразует его в тип Java.

Приведем пример регистрации выходных параметров, выполнения хранимой процедуры cstmt и считывание параметров. Методов getByte извлекает байт из первого выходного параметра, а getBigDecimal возвращает объект BigDecimal ( с тремя цифрами после десятичной точки ) из второго:

CallableStatement cstmt = con.prepareCall ( “ {call getTestData ( ?, ?) }” );

cstmt. registerOutParameter. (1, java.sql.Types.TINYINT);

cstmt. registerOutParameter. (2, java.sql.Types.DECIMAL, 3);

cstmt.executeQUery ( );

byte x = cstmt.getByte (1);

java.math.BigDecimal n = cstmt.getBigDecimal (2, 3);

В отличие от ResultSet, CallableStatement не может считывать большие значения последовательно (в потоке).

Параметры INOUT

В случае параметра, который одновременно является и входным,  и выходным (INOUT), необходимо вызывать как соответствующий метод setXXX (унаследованный от PreparedStatement), так и метод registerOutParameter. Метод setXXX устанавливает входное значение параметра, а registerOutParameter регистрирует тип выходного значения.

Типы входного и выходного значений, зарегистрированных методом registerOutParameter, должны быть одинаковыми. Для чтения выходного значения используется соответствующий метод getXXX. Например, для параметра типа byte нужно использовать метод установки значения setByte, передавать JDBC-тип данных TINYINT методу registerOutParameter и использовать getByte для чтения выходного значения.

В следующем примере вызывается хранимая процедура reviseTotal с единственным INOUT-параметром. Метод setByte устанавливает значение параметра в 25, которое будет представлено базе данных как TINYINT. Далее метод registerOutParameter регистрирует параметр как TINYINT. После выполнения хранимой процедуры возвращается значение типа TINYINT, которое будет считано методом getByte в виде типа byte языка Java.

CallableStatement cstmt = con.prepareCall ( “ {call revisrTotal ( ? ) }” );

cstmt. setByte (1, 25);

cstmt. registerOutParameter. (1, java.sql.Types.TINYINT);

cstmt.executeUpdate ( );

byte x = cstmt.getByte (1);

Возвращение значения NULL в выходных параметрах

Значение, возвращенное в выходной параметр, может быть NULL. При этом методы getXXX возвращают null, 0 или false, в зависимости от типа данных. Как и в случае с ResultSet, единственным способом узнать, вернула ли процедура 0, false или NULL, является вызов метода wasNull, который возвращает true, если последнее значение, считанное одним из методов getXXX было NULL, и false иначе.


 

А также другие работы, которые могут Вас заинтересовать

39471. Оценка налоговых рисков- методы планирования налоговых проверок 129.5 KB
  Показатели налоговой нагрузки представлены в приложении . Таким образом величина налоговой нагрузки за 2006 г.ru Группа критериев отражающих показатели деятельности плательщика Отражение в бухгалтерской или налоговой отчетности убытков в организации в течение двух и более календарных лет. Несоответствие темпов роста расходов темпам роста доходов по данным налоговой финансовой отчетности: а неоднократное приближение менее 5 к предельному значению установленных Налоговым кодексом показателей предоставляющих право применять...
39472. НАЛОГИ И НАЛОГОБЛОЖЕНИЕ 399 KB
  Курсовая работа выполняется студентами после изучения соответствующих глав Налогового Кодекса РФ, литературных источников по теме и производственной практики. За время практики студент собирает на предприятии необходимый фактический материал по теме курсовой работы. После прохождения практики собранные материалы обобщаются и студент приступает к написанию курсовой работы
39473. Порядок характеристики налогоплательщика 367 KB
  Оценка налоговой нагрузки Описать режим налогообложения исходя из вида деятельности предприятия организационноправовой формы и действующего налогового законодательства. При этом последовательно указывается: В связи с какими обстоятельствами возникли обязанности налогоплательщика плательщика сборов налогового агента ; Описание объектов обложения; Особенности формирования налоговой базы; Применяемые налоговые ставки ; Порядок исчисления налога сбора; Порядок и сроки уплаты. Кирову ИНН: 4345001066 КПП: 434501001; ОКАТО...
39475. БУХГАЛТЕРСКИЙ УЧЕТ И АНАЛИЗ 358.5 KB
  Выполняя курсовую работу следует использовать действующие законодательные акты нормативные документы определяющие методологические основы порядок организации и ведения бухгалтерского учета в организациях: Федеральный Закон О бухгалтерском учете Положение по ведению бухгалтерского учета и бухгалтерской отчетности в РФ План счетов бухгалтерского учета Инструкцию по его применению и другие а также изучить литературу по теме курсовой работы. Излагая общие положения необходимо рассмотреть порядок документального оформления хозяйственных...
39476. Проектирование корпоративных мультисервисных сетей 495.5 KB
  Технология Ethernet известна прежде всего как технология локальных вычислительных сетей имевшая некоторое количество существенных недостатков которые не позволяли строить на ее основе нормально работающие мультисервисные сети. Целью курсовой работы является создание проекта МСС для данного комплекса на базе EthernetIPсети. КРАТКОЕ ОПИСАНИЕ УСЛУГ ПРОЕКТИРУЕМОЙ СЕТИ Услуги которые предоставляет проектируемая мультисервисная сеть: Передача речи телефонная связь – данная услуга будет реализована на базе средств IPтелефонии то есть будет...
39477. Барабанне сушило для сушки піску 63 KB
  Мета роботи: розрахувати горіння палива основні розміри сушила процес сушки тепловий баланс паливоспалювального пристрою для барабанного сушила для сушки піску. Розрахунок горіння палива основних розмірів сушила теплообміну теплового балансу паливо спалювального пристрою необхідно для проектування сушила. ТЕПЛОВИЙ БАЛАНС ГОРІННЯ ПАЛИВА БАРАБАН СУШИЛА ТЕПЛООБМІН ТЕМПЕРАТУРА ПРОДУКТИВНІСТЬ ДІАГРАМА ПАЛЬНИК МАТЕРІАЛ ЗАВАНТАЖУВАЛЬНИЙ ПРИСТРІЙ ОБ’ЄМ ВОЛОГИ РОЗРАХУНОК ПАЛИВОСПАЛЮВАЛЬНИЙ ПРИСТРІЙ.6 Розрахунок горіння...
39478. РАСЧЕТ ПОКАЗАТЕЛЕЙ РАЗРАБОТКИ ОДНОРОДНОГО ПЛАСТА НА ОСНОВЕ МОДЕЛИ НЕПОРШНЕВОГО ВЫТЕСНЕНИЯ НЕФТИ ВОДОЙ В УСЛОВИЯХ ЖЕСТКОГО ВОДОНАПОРНОГО РЕЖИМА 197.5 KB
  Для большинства пластов при вытеснении из них нефти водой характерно возникновение в порах раздробленных диспернированных глобул нефти. В местах пористых сред где путь движению нефти преграждается плотными скоплениями зерен породы в тупиковых зонах в поровых ловушках остаточная нефть сохраняется в виде неподвижных глобул не извлекаемых из пористой среды даже при ее бесконечной промывки. Возникновению неподвижных глобул способствуют также различие вязкостей нефти и воды и наличие у нефти неньютоновских свойств.
39479. Взаимодействие Европейского суда по правам человека и Российской Федерации: проблемы и перспективы 236 KB
  Взаимодействие Европейского суда по правам человека и Российской Федерации: проблемы и перспективы.43 Введение Европейским судом по правам человека называют совестью Европы и это не просто красивая фраза. Это стало возможным благодаря тому что Конституция Российской Федерации впервые в юридической практике нашей страны установила международные гарантии соблюдения и защиты прав и свобод человека и гражданина: Каждый вправе в соответствии с международными договорами Российской Федерации обращаться в межгосударственные органы...