Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / java.sql.Connection есть ли способ отслеживать изменения в БД / 18 сообщений из 18, страница 1 из 1
02.03.2006, 07:52
    #33575562
Vector
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
Здравствуйте.
Пишу standalone приложение. Приложение работает с MySQL.

У меня есть интерфейс java.sql.Connection объекта для работы с базой данных - connection. Этот интерфейс находится в отдельном классе Database. Указатель на объект класса Database я передаю в конструкторы всех классов, которые работают с базой данных, будь то фрейм или какой-либо поток.

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

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

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

Куда проще и интереснее было бы использовать какое-нибудь событие самого соединения, ведь оно же должно знать о всех успешных UPDATE и DELETE.
И так как все фреймы используют одно соединение, то можно было бы легко отслеживать все изменения.
Но в данном интерфейсе нет методов для добавления слушателей событий.

Хотелось бы узнать, кто как делает.
С уважением Vector.
...
Рейтинг: 0 / 0
02.03.2006, 09:23
    #33575686
М.Голованов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
p6spy (http://www.p6spy.com/)
...
Рейтинг: 0 / 0
02.03.2006, 09:37
    #33575716
java.sql.Connection есть ли способ отслеживать изменения в БД
VectorКуда проще и интереснее было бы использовать какое-нибудь событие самого соединения, ведь оно же должно знать о всех успешных UPDATE и DELETE.
И так как все фреймы используют одно соединение, то можно было бы легко отслеживать все изменения.
А по-моему, довольно проблематично отследить изменения. Например, если через Connection СУБД отправлен следующий запрос
Код: plaintext
DELETE FROM table WHERE field = value
, то какие именно записи были удалены, знает только СУБД, и ей нет никакого смысла сообщать об этом Connection'у.
По-моему, такую задачу следует решать либо на более "высоком" уровне (при изменении данных, приложение будет указывать, кто их меняет), либо на уровне СУБД (аудит, триггера и т.п.).
...
Рейтинг: 0 / 0
02.03.2006, 09:42
    #33575742
Vector
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
Для меня важен только факт изменения.
Поясню.
У меня к одной базе может быть подключены несколько приложений.
В базе есть специальная таблица, куда каждый клиент заносит (серверное) время после своего последнего изменения. Также в каждом клиенте есть поток, который сверяет с определенной периодичностью значение своего
времени последнего изменения и времени в этой таблице. Если они не совпадают, то вызывается функция обносвления данных во всех фреймах.
...
Рейтинг: 0 / 0
02.03.2006, 15:45
    #33577413
ТимоН
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
авторУ меня есть интерфейс java.sql.Connection объекта для работы с базой данных - connection. Этот интерфейс находится в отдельном классе Database. Указатель на объект класса Database я передаю в конструкторы всех классов, которые работают с базой данных, будь то фрейм или какой-либо поток.
Не в тему топика, но такую вещь лучше синглтоном сделать. Паттерн если не в курсе.
...
Рейтинг: 0 / 0
02.03.2006, 15:56
    #33577456
ТимоН
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
А теперь в тему.
Проше всего функции UPDATE и DELETE оформить в виде хранимых процедур, а помимо выполнения обновления, ... фиксировать кто, куда, зачем, ... в другой таблице.
...
Рейтинг: 0 / 0
02.03.2006, 16:44
    #33577675
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
VectorУ меня есть интерфейс java.sql.Connection
По другому поводу, но мне однажды потребовалось обмануть готовые библиотеки. Для этого я подменил jdbc-драйвер, разрегистрировал стандартный и зарегистрировал под его именем свою прокладку. Оказалось весьма и весьма несложно. Можно таким образом всадить необходимый notification.

Хотя я отметил бы, что по-хорошему это задача для Data Access Layer, и это одна из причин, по которым я предпочитаю не просто использовать стандартные классы, но сразу делать от них тривиальных собственных наследников и использовать их.
...
Рейтинг: 0 / 0
02.03.2006, 17:23
    #33577857
java.sql.Connection есть ли способ отслеживать изменения в БД
Оказывается, автор не сразу дал точную постановку задачи, но уточнил
VectorДля меня важен только факт изменения.
Поясню.
У меня к одной базе может быть подключены несколько приложений.
В базе есть специальная таблица, куда каждый клиент заносит (серверное) время после своего последнего изменения. Также в каждом клиенте есть поток, который сверяет с определенной периодичностью значение своего
времени последнего изменения и времени в этой таблице. Если они не совпадают, то вызывается функция обносвления данных во всех фреймах.

В оригинальном java.sql события, уведомляющего о том, что в БД произошли изменения, нет. Но некоторые СУБД реализуют такую возможность. Есть ли она в MySQL, не знаю.

В любом случае, процитированная идея вполне работоспособна. По крайней мере при малом количестве пользователей или невысокойих активности.
...
Рейтинг: 0 / 0
02.03.2006, 17:35
    #33577902
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
для прокладок: java.lang.reflect.Proxy - одно из удобных решений. регистрация/дерегистрация драйвера при этом не нужна.
...
Рейтинг: 0 / 0
02.03.2006, 18:01
    #33578013
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
Timmдля прокладок: java.lang.reflect.Proxy - одно из удобных решений. регистрация/дерегистрация драйвера при этом не нужна.
Спасибо за информацию, пороюсь на досуге. Не знал об этой возможности; быстрым поиском по гуглю удачных примеров не нашел.

Сходу я не увидел, каким образом этот прокси сам по себе, без манипуляций с драйвером, поможет поймать вызов драйвера. Если не трудно, пожалуйста проясните это момент.
...
Рейтинг: 0 / 0
02.03.2006, 18:30
    #33578119
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
сам прокси ничего не ловит.
Он позволяет создавать на лету объект, класс которого реализует заданный набор интерфейсов (ех. Statement), при этом реализацию своей логики он передает InvocationHandler'у. Т.е. выглядит все примерно так:
1. пишется класс реализующий InvocationHandler. у него один метод: invoke(Object proxy, Method method, Object[] args).
2. создается прокси инстанс, с логикой этого хэндлера.
3. вызов методов прокси инстанса диспатчится хэндлером.
4. в хэндлер можно добавить свою логику - например для трейса. собственно этого достаточно чтобы избежать манипуляций с драйвером - его логика остается.
...
Рейтинг: 0 / 0
02.03.2006, 18:38
    #33578144
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
Timm3. вызов методов прокси инстанса диспатчится хэндлером.
Это понятно. По сути, прокси позволяет избежать реализации набора "тупых" методов (состоящих из одной строки вызова оригинального метода) за счет необходимости реализации большого switch-а в методе хандлера.

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

Есть библиотека, которой я делаю

Код: plaintext
 new  ThisLibrarySession (username, password)

Эта библиотека создает jdbc-соединение и использует его. Мне нужно, чтобы использовались не стандартные классы драйвера, но доработанные мной. Куда и как мне здесь всунуть прокси?
...
Рейтинг: 0 / 0
03.03.2006, 10:38
    #33579104
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
Код: plaintext
 new  ThisLibrarySession (username, password)
это конечно круто... но непонятно :-) что она должна делать. вот пример из книги (Java Refelection in Action):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
     public   class  TracingIH  implements  InvocationHandler
    {
         public   static  Object createProxy(Object obj, PrintWriter out)
        {
             return  Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                                          obj.getClass().getInterfaces(),
                                           new  TracingIH(obj, out));
        }

         private  Object target;
         private  PrintWriter out;

         private  TracingIH(Object obj, PrintWriter out)
        {
            target = obj;
             this .out = out;
        }

         public  Object invoke(Object proxy, Method method, Object[] args)
                 throws  Throwable
        {
            Object result =  null ;
             try 
            {
                out.println(method.getName() + "(...) called");
                result = method.invoke(target, args);
            }
             catch  (InvocationTargetException e)
            {
                out.println(method.getName() + " throws " + e.getCause());
                 throw  e.getCause();
            }
            out.println(method.getName() + " returns");
             return  result;
        }
    }
...
Рейтинг: 0 / 0
03.03.2006, 11:26
    #33579352
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
Timm
Код: plaintext
 new  ThisLibrarySession (username, password)
это конечно круто... но непонятно :-) что она должна делать.
Я же вроде как сказал - внутри себя этот объект создает jdbc-соединение и использует его. Мне нужно вмешаться в его общение с БД. Вы говорите о том, что это можно сделать без подмены драйвера за счет создания прокси. Я пытаюсь выяснить - как.

Timmвот пример из книги (Java Refelection in Action):
Хм. И?

Все подобные примеры, которые я вчера просмотрел, подразумевали собственноручное подсовывание созданного прокси-объекта тому, кто собирается им пользоваться. В том числе и этот.

Итак, у нас есть объект, который внутри себя делает

Код: plaintext
Connection conn = DriverManager.getConnection ("jdbc:oracle:траляля");

Мне нужно, чтобы при этом он получил экземпляр моего класса. И я пока не понимаю, как сделать это без подмены драйвера.
...
Рейтинг: 0 / 0
03.03.2006, 11:38
    #33579414
java.sql.Connection есть ли способ отслеживать изменения в БД
softwarer
Код: plaintext
Connection conn = DriverManager.getConnection ("jdbc:oracle:траляля");

Мне нужно, чтобы при этом он получил экземпляр моего класса. И я пока не понимаю, как сделать это без подмены драйвера.
А ты получай Connection через java.sql.DataSource - его реализацию легко сделать - в нем и будешь осуществлять подмену. А имя класса ( реализцющего DataSource ) пропиши в конфиг/куда угодно.
...
Рейтинг: 0 / 0
03.03.2006, 12:35
    #33579655
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
softwarer...
Итак, у нас есть объект, который внутри себя делает

Код: plaintext
Connection conn = DriverManager.getConnection ("jdbc:oracle:траляля");

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

Код: plaintext
Connection conn = TracingIH.createProxy("user", "pass", "url");
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
 public   class  TracingIH  implements  InvocationHandler
    {
         public   static  Object createProxy(String user, String pass, String url)
        {
            Conenction conn = DriverManager.getConnection(url, user, pass);
             return  Proxy.newProxyInstance(conn.getClass().getClassLoader(),
                                          conn.getClass().getInterfaces(),
                                           new  TracingIH(conn, out));
        }

         private  Object target;
         private  PrintWriter out;

         private  TracingIH(Object obj, PrintWriter out)
        {
            target = obj;
             this .out = out;
        }

         public  Object invoke(Object proxy, Method method, Object[] args)
                 throws  Throwable
        {
            Object result =  null ;
             try 
            {
                // своя логика.
                out.println(method.getName() + "(...) called");
                //вызов на стандартном Connection
                result = method.invoke(target, args);
            }
             catch  (InvocationTargetException e)
            {
                out.println(method.getName() + " throws " + e.getCause());
                 throw  e.getCause();
            }
            out.println(method.getName() + " returns");
             return  result;
        }
    }
кривоватый пример, конечно. но смысл то понятен: добиться перехватывания методов определенного класса и выполнять свою логику. все. никаких подмен драйверов.
softwarerВсе подобные примеры, которые я вчера просмотрел, подразумевали собственноручное подсовывание созданного прокси-объекта тому, кто собирается им пользоваться. В том числе и этот.
что значит собственноручное? ну используется какой то factory метод. в нем и будет добавлено проксирование при необходимости. я вообще не понимаю, зачем в коде писать прямо DriverManager.getConnection(...). это должно быть спрятано.
...
Рейтинг: 0 / 0
03.03.2006, 17:22
    #33580985
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
Ненавижу регистрациюА ты получай Connection через java.sql.DataSource
Я-то могу его получать как угодно. Но вот декомпилировать библиотеку и править способ, которым получает она - не хочется. Точнее, явно невыгодно (подмену драйвера я свалял за полчаса, а патчить под себя каждую вновь выходящую версию библиотеки потребует явно больше усилий).
...
Рейтинг: 0 / 0
03.03.2006, 17:36
    #33581026
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
java.sql.Connection есть ли способ отслеживать изменения в БД
Timmя говорил о проксировании стандартного, а не о его подмене.
Вы сказали о том, что при применении этой технологии подмена драйвера не обязательна. Я прошу таки рассказать, как эта технология позволяет без нее обойтись.

Код: plaintext
Connection conn = TracingIH.createProxy("user", "pass", "url");
И я об этом же. Явно создать этот объект... и как я его потом подсуну библиотеке, которая делает собственный getConnection?

Timmкривоватый пример, конечно. но смысл то понятен: добиться перехватывания методов определенного класса и выполнять свою логику. все. никаких подмен драйверов.
Да вот нет, смысл как раз непонятен. Мне нужно перехватывать не методы определенного класса - это делается тривиальным наследованием - а методы определенного объекта, причем этот объект создается в недоступном мне месте.

Timmчто значит собственноручное? ну используется какой то factory метод. в нем и будет добавлено проксирование при необходимости. я вообще не понимаю, зачем в коде писать прямо DriverManager.getConnection(...). это должно быть спрятано.
Хм. Опуская прочие моменты - может быть getConnection и незачем писать, но как факт какие-то идиоты его написали. И мне нужно, чтобы этот getConnection вернул мой объект.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / java.sql.Connection есть ли способ отслеживать изменения в БД / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]