Logo    
Деловая газета CitCity.ru CITKIT.ru - все об Open Source Форумы Все публикации Учебный центр Курилка
CitForum    CITForum на CD    Подписка на новости портала Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

08.06.2009

Google
WWW CITForum.ru

Новости мира IT:

Все новости на CitCity.ru

2008 г.

Базы данных. Вводный курс

Сергей Кузнецов

Назад Содержание Вперёд

Лекция 13. Методы управления транзакциями. Сихронизационные блокировки, временные метки и версии

13.1. Введение

Поддержка механизма транзакций – показатель уровня развитости СУБД. Корректное поддержание транзакций одновременно является основой обеспечения целостности баз данных (и поэтому транзакции вполне уместны и в однопользовательских персональных СУБД), а также составляют базис изолированности пользователей в многопользовательских системах. Часто эти два аспекта рассматриваются по отдельности, но на самом деле они взаимосвязаны, что и будет показано в этой лекции.

13.2. Общее понятие транзакции и основные характеристики транзакций

Более точно, в современных СУБД поддерживается понятие транзакции, характеризуемое аббревиатурой ACID (Atomicy, Consistency, Isolation и Durability). В соответствии с этим понятием под транзакцией разумеется последовательность операций над базой данных, обладающая следующими свойствами.

  • Атомарность (Atomicy). Это свойство означает, что результаты всех операций, успешно выполненных в пределах транзакции, должны быть отражены в состоянии базы данных, либо в состоянии базы данных не должно быть отражено действие ни одной операции (конечно, здесь речь идет об операциях, изменяющих состояние базы данных). Свойство атомарности, которое часто называют свойством “все или ничего”, позволяет относиться к транзакции, как к динамически образуемой составной операции над базой данных (в общем случае состав и порядок выполнения операций, выполняемых внутри транзакции, становится известным только на стадии выполнения).
  • Согласованность (Consistency). В классическом смысле это свойство означает, что транзакция может быть успешно завершена с фиксацией результатов своих операций только в том случае, когда действия операций не нарушают целостность базы данных, т.е. удовлетворяют набору ограничений целостности, определенных для этой базы данных. Это свойство расширяется тем, что во время выполнения транзакции разрешается устанавливать точки согласованности и явным образом проверять ограничения целостности. (С точки зрения автора, в контексте баз данных термины согласованность и целостность эквивалентны. Единственным критерием согласованности данных является их удовлетворение ограничениям целостности, т.е. база данных находится в согласованном состоянии тогда и только тогда, когда она находится в целостном состоянии.)
  • Изоляция (Isolation). Требуется, чтобы две одновременно (параллельно или квазипараллельно) выполняемые транзакции никоим образом не действовали одна на другую. Другими словами, результаты выполнения операций транзакции T1 не должны быть видны никакой другой транзакции T2 до тех пор, пока транзакция T1 не завершится успешным образом.
  • Долговечность (Durability). После успешного завершения транзакции все изменения, которые были внесены в состояние базы данных операциями этой транзакции, должны гарантированно сохраняться, даже в случае сбоев аппаратуры или программного обеспечения. Этому аспекту транзакционных систем посвящается лекция 14.

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

13.2.1. Атомарность транзакций

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

Лозунгом транзакции является «Все или ничего»: при завершении транзакции оператором COMMIT (высокоуровневый аналог операции END TRANSACTION в интерфейсе RSS, см. лекцию 12) результаты гарантированно фиксируются во внешней памяти (смысл термина commit состоит в запросе «фиксации» результатов транзакции); при завершении транзакции оператором ROLLBACK (высокоуровневый аналог операции RESTORE в интерфейсе RSS, см. лекцию 12) результаты гарантированно отсутствуют во внешней памяти (смысл термина rollback состоит в запросе ликвидации результатов транзакции).

Каким образом в СУБД поддерживаются индивидуальные откаты транзакций, описывается в лекции 14.

13.2.2. Транзакции и целостность баз данных

Понятие транзакции имеет непосредственную связь с понятием целостности базы данных. Очень часто база данных может обладать такими ограничениями целостности, которые просто невозможно не нарушить, выполняя только один оператор изменения базы данных. Например, в базе данных СЛУЖАЩИЕ-ОТДЕЛЫ (см. лекцию 1) естественным ограничением целостности является совпадение значения атрибута ОТД_РАЗМЕР в кортеже таблицы ОТДЕЛЫ, описывающей данный отдел (например, отдел 625), с числом кортежей таблицы СЛУЖАЩИЕ, таких, что значение поля СЛУ_ОТД_НОМЕР равно 625. Как в этом случае принять на работу в отдел 625 нового сотрудника? Независимо от того, какая операция будет выполнена первой, вставка нового кортежа в таблице СОТРУДНИКИ или модификация существующего кортежа в отношении ОТДЕЛЫ, после выполнения операции база данных окажется в нецелостном состоянии.

Поэтому для поддержки подобных ограничений целостности допускается их нарушение внутри транзакции с тем условием, чтобы к моменту завершения транзакции условия целостности были соблюдены. В системах с развитыми средствами ограничения и контроля целостности каждая транзакция начинается при целостном состоянии базы данных и должна оставить это состояние целостными после своего завершения. Несоблюдение этого условия приводит к тому, что вместо фиксации результатов транзакции происходит ее откат (т.е. вместо оператора COMMIT выполняется оператор ROLLBACK), и база данных остается в таком состоянии, в котором находилась к моменту начала транзакции, т.е. в целостном состоянии.

Более точно, различаются два вида ограничений целостности: немедленно проверяемые и откладываемые. К немедленно проверяемым ограничениям целостности относятся такие ограничения, проверку которых бессмысленно или даже невозможно откладывать. Примером ограничения, проверку которого откладывать бессмысленно, являются ограничения домена (например, возраст сотрудника не может превышать 150 лет). Более сложным ограничением, проверку которого невозможно отложить, является следующее: зарплата сотрудника не может быть увеличена за одну операцию более чем на 100000 рублей. Немедленно проверяемые ограничения целостности соответствуют уровню отдельных операторов языкового уровня СУБД. При их нарушениях не производится откат транзакции, а лишь отвергается соответствующий оператор.

Откладываемые ограничения целостности – это ограничения на базу данных, а не на какие-либо отдельные операции. По умолчанию такие ограничения проверяются при конце транзакции, и их нарушение вызывает автоматическую замену оператора COMMIT на оператор ROLLBACK. Однако в некоторых системах поддерживается специальный оператор насильственной проверки ограничений целостности внутри транзакции. Если после выполнения такого оператора обнаруживается, что условия целостности не выполнены, пользователь может сам выполнить оператор ROLLBACK с откатом транзакции до ее начала или до установленной ранее точки сохранения или постараться устранить причины нецелостного состояния базы данных внутри транзакции (видимо, это осмысленно только при использовании интерактивного режима работы).

Заметим, что концептуально в момент завершения транзакции проверяются все откладываемые ограничения целостности, определенные в этой базе данных. Однако в реализации стремятся при выполнении транзакции динамически выделить те ограничения целостности, которые действительно могли бы быть нарушены. Например, если при выполнении транзакции над базой данных СЛУЖАЩИЕ-ОТДЕЛЫ в ней не выполнялись операторы вставки или удаления кортежей из отношения СЛУЖАЩИЕ, то проверять упоминавшееся выше ограничение целостности не требуется (а для проверки подобных ограничений требуется достаточно большая работа).

Понятно, что описанный механизм поддержки целостности баз данных обеспечивает требуемое свойство транзакций: никакая транзакция не может быть зафиксирована, если ее действия нарушили целостность базы данных. Однако в этом подходе имеются два серьезных дефекта.

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

Простое и элегантное решение этой проблемы предлагается в [1.5]. Авторы предлагают отказаться от откладываемых ограничений целостности базы данных, а вместо этого ввести составные операторы изменения базы данных (нечто наподобие блоков BEGIN … END, поддерживаемых в языках программирования). После выполнения каждого такого блока (или отдельного оператора изменения базы данных, используемого без операторов начала и конца блока) база данных должна находится в целостном состоянии. Если составной оператор нарушает ограничение целостности, то он целиком отвергается, и вырабатывается соответствующий код ошибки. Транзакция в этом случае не откатывается. Понятно, что при использовании такого подхода при выполнении оператора COMMIT не требуется проверять ограничения целостности, и каждая зафиксированная транзакция будет оставлять базу данных в целостном состоянии.

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

13.2.3. Изолированность транзакций

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

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

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

Отсутствие потерянных изменений (первый уровень изолированности)

Рассмотрим сценарий совместного выполнения двух транзакций, показанный на рис. 13.1. В момент времени t1 транзакция T1 изменяет объект базы данных o (выполняет операцию W(o)). До завершения транзакции T1 в момент времени t2 > t1 транзакция T2 также изменяет объект o. В момент времени t3 > t2 транзакция T2 завершается оператором ROLLBACK (например, по причине нарушения ограничений целостности).


Рис. 13.1. Потерянные изменения

Тогда при повторном чтении объекта o (выполнении операции R(o)) в момент времени t4 > t3 транзакция T1 не видит своих изменений этого объекта, произведенных ранее (в частности, из-за этого может не удастся фиксация этой транзакции, что, возможно, повлечет потерю изменений у еще одной транзакции и т.д.).

Такая ситуация называется ситуацией потерянных изменений. Естественно, она противоречит требованию изолированности пользователей. Чтобы избежать такой ситуации в транзакции T1 требуется, чтобы до завершения транзакции T1 никакая другая транзакция не могла изменять никакой измененный транзакцией T1 объект o (в частности, достаточно заблокировать доступ по изменению к объекту o до завершения транзакции T1). Отсутствие потерянных изменений является минимальным требованием к СУБД при обеспечении изолированности одновременно выполняемых транзакций.

Отсутствие чтения «грязных» данных (второй уровень изолированности)

Рассмотрим сценарий совместного выполнения транзакций T1 и T2, показанный на рис. 13.2. В момент времени t1 транзакция T1 изменяет объект базы данных o (выполняет операцию W(o)). В момент времени t2 > t1 транзакция T2 читает объект o (выполняет операцию R(o)). Поскольку транзакция T1 еще не завершена, транзакция T2 видит несогласованные «грязные» данные. В частности, в момент времени t3 > t2 транзакция T1 может завершиться откатом (например, по причине нарушения ограничений целостности).


Рис. 13.2. «Грязные» чтения

Эта ситуация тоже не соответствует требованию изолированности пользователей (каждый пользователь начинает свою транзакцию при согласованном состоянии базы данных и имеет право видеть только согласованные данные). Чтобы избежать ситуации чтения "грязных" данных, до завершения транзакции T1, изменившей объект базы данных o, никакая другая транзакция не должна читать объект o (например, достаточно заблокировать доступ по чтению к объекту o до завершения изменившей его транзакции T1).

Отсутствие неповторяющихся чтений (третий уровень изоляции)

Рассмотрим сценарий совместного выполнения транзакций T1 и T2, показанный на рис. 13.3. В момент времени t1 транзакция T1 читает объект базы данных o (выполняет операцию R(o)). До завершения транзакции T1 в момент времени t2 > t1 транзакция T2 изменяет объект o (выполняет операцию W(o)) и успешно завершается оператором COMMIT. В момент времени t3 > t2 транзакция T1 повторно читает объект o и видит его измененное состояние.


Рис. 13.3. Неповторяющиеся чтения

Чтобы избежать неповторяющихся чтений, до завершения транзакции T1 никакая другая транзакция не должна изменять объект o (для этого достаточно заблокировать доступ по записи к объекту o до завершения транзакции T1). Часто это является максимальным требованием к средствам обеспечения изолированности транзакций, хотя, как будет видно немного позже, отсутствие неповторяющихся чтений еще не гарантирует реальной изолированности пользователей.

Заметим, что существует возможность обеспечения разных уровней изолированности для разных транзакций, выполняющихся в одной системе баз данных (кстати, соответствующие операторы были предусмотрены уже в стандарте SQL:1992). Как уже отмечалось, для корректного соблюдения ограничений целостности достаточен первый уровень. Существует ряд приложений, которым хватает первого уровня изолированности (например, прикладные или системные статистические утилиты, для которых некорректность индивидуальных данных несущественна). При этом удается существенно сократить накладные расходы СУБД и повысить общую эффективность.

Проблема фантомов

К более тонким проблемам изолированности транзакций относится так называемая проблема кортежей-«фантомов», приводящая к ситуациям, которые также противоречат изолированности пользователей. Рассмотрим сценарий, показанный на рис. 13.4.


Рис. 13.4. Проблема фантомов

В момент времени t1 транзакция T1 выполняет оператор выборки кортежей таблицы Tab с условием выборки S (т.е. выбирается часть кортежей таблицы Tab, удовлетворяющих условию S). До завершения транзакции T1 в момент времени t2 > t1 транзакция T2 вставляет в таблицу Tab новый кортеж r, удовлетворяющий условию S, и успешно завершается. В момент времени t3 > t2 транзакция T1 повторно выполняет тот же оператор выборки, и в результате появляется кортеж, который отсутствовал при первом выполнении оператора.

Конечно, такая ситуация противоречит идее изолированности транзакций и может возникнуть даже на третьем уровне изолированности транзакций. Чтобы избежать появления кортежей-фантомов, требуется более высокий «логический» уровень изоляции транзакций. Идеи требуемого механизма (предикатные синхронизационные блокировки) появились также еще во время выполнения проекта System R, но в большинстве систем не реализованы.

13.2.4. Сериализация транзакций

Чтобы добиться изолированности транзакций, в СУБД должны использоваться какие-либо методы регулирования совместного выполнения транзакций.

Пусть в системе одновременно выполняется некоторое множество транзакций S = {T1, T2, …, Tn}. План (способ) выполнения набора транзакций S (в котором, вообще говоря, чередуются или реально параллельно выполняются операции разных транзакций) называется сериальным, если результат совместного выполнения транзакций эквивалентен результату некоторого последовательного выполнения этих же транзакций (Ti1, Ti2, …, Tin).

Сериализация транзакций – это механизм их выполнения по некоторому сериальному плану. Обеспечение такого механизма является основной функцией компонента СУБД, ответственного за управление транзакциями. Система, в которой поддерживается сериализация транзакций, обеспечивает реальную изолированность пользователей.

Основная реализационная проблема состоит в выборе метода сериализации набора транзакций, который не слишком ограничивал бы чередование их операций или реальную параллельность. Приходящим на ум тривиальным решением является действительно последовательное выполнение транзакций. Но существуют ситуации, в которых можно выполнять операторы разных транзакций в любом порядке с сохранением свойства сериальности. Примерами могут служить только читающие транзакции, а также транзакции, не конфликтующие по объектам базы данных.

Между транзакциями T1 и T2 могут существовать следующие виды конфликтов:

  • W/W – транзакция T2 пытается изменять объект, измененный не закончившейся транзакцией T1 (наличие такого конфликта может привести к возникновению ситуации потерянных изменений);
  • R/W – транзакция T2 пытается изменять объект, прочитанный не закончившейся транзакцией T1 (наличие такого конфликта может привести к возникновению ситуации неповторяющихся чтений);
  • W/R – транзакция T2 пытается читать объект, измененный не закончившейся транзакцией T1 (наличие такого конфликта может привести к возникновению ситуации «грязного» чтения).

Практические методы сериализации транзакций основываются на учете этих конфликтов.

Назад Содержание Вперёд

Западный МВА с обучением в Петербурге. Топ-10 школ Европы по версии FT.
Адрес и телефон  ·  www.vlerick.ru
Услуги датацентра. Размещение оборудования. Аренда стоек. Аренда каналов.
Адрес и телефон  ·  www.dataplanet.ru  ·  Москва
Системы хранения данных Axus, Xyratex, DatStor. Файл-серверы Flagman S.
Адрес и телефон  ·  www.stss.ru

Подписка на новости IT-портала CITForum.ru
(библиотека, CITKIT.ru, CitCity)

Новые публикации:

3 июня

  • Специализированные языки (М.Шапиро, перевод: С.Кузнецов)

    CITKIT.ru:

  • Chromium для Linux: первые впечатления
  • Кое-что о настройке сети в современных Ubuntu'идах
  • Дистрибутивы на флэшках: не хочу больше болванить!
  • Самый главный аргумент
  • 27 мая

    CitCity:

  • Экономический кризис и рынок IT. Перспективы внедрения BI
  • Роль интеграции данных в условиях экономического спада
  • Причины неэффективного внедрения Business Intelligence

    CITKIT.ru:

  • Виктор Иванников: зачастую все начиналось именно с открытого кода
  • Asus EeePC 2G: недобук par exellence
  • Linux'ы на недобуке: кому прижиться?
  • Еще раз о копирайте
  • 20 мая

    CitCity:

  • Интервью с Сураджитом Чаудхари

    CITKIT.ru:

  • Synaptic в Xubuntu: общие сведения
  • Synaptic в Xubuntu: настройки
  • Нетбук на батарейках: первая ласточка
  • Краткая история копирайта
  • 13 мая

    Раздел Классика баз данных:

    Обзор журнала Computer:

    CITKIT.ru:

  • Размышления у "Пиратской бухты"-2
  • Сколько пакетов нужно для счастья?
  • Стратегия дисковой разметки
  • Xubuntu 9.04: впечатления
  • Ubuntu: животные-эпонимы
  • 6 мая

    Обзоры журнала Computer:

    CITKIT.ru:

  • Тестируем ext4
  • Танцующий Медведь
  • Свободная пятерка
  • Рассуждения о микроблоггинге
  • 29 апреля

  • Материалы конференции "Корпоративные базы данных-2009"
  • CitCity:

  • С.Кузнецов. Облака спускаются на землю (отчет о конференции)

    CITKIT.ru:

  • Дискуссия о нетбуках:

  • Блогометки:

    22 апреля

  • HP Oracle Exadata Storage Server – оптимизированная платформа для Oracle BI-хранилищ данных
  • CITKIT.ru:

  • Еще раз о без-win'ных машинах: кому и зачем они нужны?
  • FOSS на Руси: революционная ситуация?
  • Размышления у "Пиратской бухты"
  • 15 апреля

    CITKIT.ru:

  • OpenSolaris на ноутах Toshiba, или как следует бороться с засильем сами знаете кого
  • Red Hat, hardlinks и сетевые настройки
  • От GRUB до GRUB4DOS
  • Сергей Голубев. Цикл "Linux в школе":
  • Windows XP - завершение поддержки
  • 8 апреля

  • Раздел Классика баз данных:

    CITKIT.ru:

  • Zenbook. Инструментальная настройка
  • Zenwalk. Большая чистка
  • Установка PC-BSD 7.1-RC1. Приключения и впечатления
  • Смесь бульдога с носорогом, или Debian GNU/kFreeBSD
  • Один на один с Windows XP
  • 1 апреля

  • М.Ривкин. Тенденции развития универсальных коммерческих СУБД
  • Раздел Классика баз данных:

    CITKIT.ru:

  • И обратно о лицензиях: 1. По мотивам RMS
  • И обратно о лицензиях: 2. По мотивам ESR
  • Zenbook. Инициализация системы
  • О поддержке оборудования "на пальцах"
  • 25 марта

  • С.Кузнецов. Оптимизация запросов в коммерческих СУБД в начале 1990-х
  • CITKIT.ru:

  • Леонид Сомс: разработчикам надоели войны "остроконечников" с "тупоконечниками"
  • Новая статья из цикла "Железный марш":

  • Блогометки:

    18 марта

  • С.Кузнецов. О пользе классики, полу-классики и не-классики вообще
  • Переводы:

    CITKIT.ru:

  • С.Голубев. Минкомсвязи против торговли байтами
  • Блогометки:

  • S2ram - способ заставить suspend-to-RAM работать "из коробки"
  • pm-utils - openSUSE

    12 марта

  • Услуги операторов связи для создания корпоративных сетей передачи данных
  • CITKIT.ru:

  • Дмитрий Комиссаров: "АйТи" считает рынок СПО очень перспективным
  • Zenwalk 6.0: впечатления от обновления
  • Без-Win'ные машины: несколько крамольных соображений
  • Колонки А.Федорчука из журнала Linuxformat
  • 4 марта

  • С.Д.Кузнецов. И снова о вечной проблеме отсутствующей информации:

  • Раздел Классика баз данных:

    CITKIT.ru:

  • Цикл А.Федорчука "CRUX: На пути к простоте":

  • С. Голубев. Околоправовой ликбез для пользователя
  • 25 февраля

  • Раздел Классика баз данных:

    CITKIT.ru:

  • Новый цикл А.Федорчука "CRUX: На пути к простоте":

  • С. Кузнецов. Рабы закона Мура
  • С. Голубев. Господдержка СПО: что это такое и кому это надо
  • 19 февраля

  • Раздел Классика баз данных:

    CITKIT.ru:

  • С.Голубев — СПО и государство:

  • Новая статья из цикла "Железный марш":

    CitCity:

  • Рынок бизнес-аналитики: результаты исследования IDC
  • Рынок СУБД для Хранилищ данных. Результаты исследования Gartner за 2008 год
  • BI 2008. Обзор минувшего года

    11 февраля

  • Раздел Классика баз данных:

    Обзоры журнала Computer:

    CITKIT.ru:

  • Вторая версия книги А. Федорчука "Zenwalk. Приобщение к Linux". Глава:

  • В.Попов: Загрузить Linux на удаленном win-хосте
  • А.Федорчук, А.Деева: Тетя Ася приехала...
  • 4 февраля

  • Обеспечение высокопродуктивного программирования для современных параллельных платформ

  • Компиляция программ для современных архитектур

  • Программная среда для динамического анализа бинарного кода

  • Раздел Классика баз данных:

    CITKIT.ru:

  • Вторая версия книги А. Федорчука "Zenwalk. Приобщение к Linux". Главы:

  • Новая статья из цикла С.Голубева "Железный марш":

    28 января

  • Перспективы интеграции методов верификации программного обеспечения

  • Ориентированные на приложения методы хранения XML-данных

  • Анализ текстовых документов для извлечения тематически сгруппированных ключевых терминов

  • Раздел Классика баз данных:

    CITKIT.ru:

  • Знакомство с btrfs (А. Федорчук)
  • Преобразование ext3fs в btrfs
  • Использование Btrfs на нескольких устройствах
  • 20 января

  • Раздел Классика баз данных:

    CITKIT.ru:

  • LiveCD:
  • Zenwalk 5.4 beta1: новый шаг на пути Дзэн
  • Все публикации >>>




    IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей PR-акции, размещение рекламы — тел. +7 495 4119920, ICQ 232284597 Пресс-релизы — pr@citcity.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
    Copyright © 1997-2000 CIT, © 2001-2009 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...