Форум программистов, компьютерный форум, киберфорум
Java EE (J2EE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789

Как быть, когда блок finally нужен и как применить com.google.common.io.Closer

22.09.2018, 13:58. Показов 1398. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
вот например в таком случае.


Кликните здесь для просмотра всего текста
Java
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
 
import static com.training.carshop.validate.object.ValidateObjectNotNull.isNullObjects;
import static com.training.carshop.validate.string.ValidateArgumentString.isBlank;
 
 
/**
 * Создан разработчиком IT
 * Дата 26.08.2018
 */
public class ConnectionPool extends Constants {
 
    private static final ConnectionPool pool = new ConnectionPool();
 
    public static ConnectionPool getPool() {
        return pool;
    }
 
 
    private DataSource dataSource;
 
    private ConnectionPool() {
        Properties properties;
        String nameJndiResource;
        try {
            if (isBlank(PATH_TO_PROPERTIES_JNDI)) {
                throw new ValidateException(MESSAGE_NOT_EMPTY_STR);
            }
 
            properties = new ClassPathPropertiesReader().getProperties(PATH_TO_PROPERTIES_JNDI);
 
        } catch (IOException e) {
            throw new ConnectionException(MESSAGE_EXCEPTION_FILE_JNDI, e);
        }
 
        isNullObjects(properties);
 
        try {
            nameJndiResource = properties.getProperty(JNDI_LINK);
            Context initContext = new InitialContext();
            Context rootContext = (Context) initContext.lookup("java:comp/env");
            dataSource = (DataSource) rootContext.lookup(nameJndiResource);
        } catch (NamingException e) {
            throw new ConnectionException(MESSAGE_LOOKUP_JNDI, e);
            /* Надо подумать, как сделать не проброс исключения и остановку программы, а
            в случае отлова ошибки подключения, выполнить переход на страницу, в которой
            будет сообщено пользователю, что база данных не работатет и нужно попробовать
            подключится позже.
             А адиминстратору выдать на косноль предупреждение, а также сформировать отправку
             сообщения на почту
             */
        }
    }
 
    public Connection getConnection() {
        try {
            dataSource.getConnection().setAutoCommit(false);
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new ConnectionException(MESSAGE_CONNECTION, e);
        }
    }
 
    /**
     * Методы для закрытия поптоков
     * Применяется принцип делегирования
     */
    public void closeDbResources(Connection connection) {
        closeDbResources(connection, null, null);
    }
 
    public void closeDbResources(ResultSet resultSet) {
        closeDbResources(null, null, resultSet);
    }
 
    public void closeDbResources(Connection connection, Statement statement) {
        closeDbResources(connection, statement, null);
    }
 
 
    private void closeDbResources(Connection connection, Statement statement, ResultSet resultSet) {
        closeResultSet(resultSet);
        closeStatement(statement);
        closeConnection(connection);
    }
 
 
    private void closeConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                System.out.println("Error: Connection has not been closed!");
            }
        }
    }
 
    private void closeStatement(Statement statement) {
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                System.out.println("Error: Statement has not been closed!");
            }
        }
    }
 
    private void closeResultSet(ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                System.out.println("Error: ResultSet has not been closed!");
            }
        }
    }
 
    /*  отменить действия с базой данных, в  текущем запросe (отменить транзакцию)
       Отмена всех изменений, внесенных в текущую транзакцию
       и освобождение всех блокировок базы данных, удерживаемые в данный момент
       текущим объектoм Connection. Этот метод должен быть
       использован только при отключенном режиме автоматической фиксации транзакций
      (auto-commit mode = disable).
     @exception SQLException - при возникновении ошибки доступа к базе данных,
     rollback() метод вызывается при участии в распределенной транзакции,
     этот метод вызывают на закрытом соединении, или когда объект connection
     находится в auto-commit mode  */
    public static void rollback(Connection conn) {
        try {
            conn.rollback();
        } catch (Exception e) {
            System.out.println("Rollback changes as a result of a transaction that failed to undo.");
        }
    }
 
 
}



Кликните здесь для просмотра всего текста
Java
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
     * @see CarDao
     * @param carEntity - объект для хранения одной записи обрабатываемого бизнес-объекта
     */
    @Override
    public CarEntity storeCar(CarEntity carEntity) throws DaoException {
 
        isNullObjects(carEntity);
 
        Connection connection;
        PreparedStatement statement = null;
        String sql;
 
        sql = "INSERT INTO `cars` (`model`, `color`, `speed`, `fuel_consumption`, " +
                "`quantity`, `cost`, `date_delivery`,`uuid`) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
 
        connection = ConnectionPool.getPool().getConnection();
 
        try {
            statement = connection.prepareStatement(sql);
            statement.setString(ONE, carEntity.getModel());
            statement.setString(TWO, carEntity.getColor());
            statement.setInt(THREE, carEntity.getSpeed());
            statement.setInt(FOUR, carEntity.getFuelConsumption());
            statement.setInt(FIVE, carEntity.getQuantity());
            statement.setInt(SIX, carEntity.getCost());
            setDateToStatement(statement, SEVEN, carEntity.getDateDelivery());
            statement.setString(EIGHT, carEntity.getUuid());
 
            statement.executeUpdate();
            connection.commit();
 
            Integer storeId = loadStoreId(statement);
            CarEntity storeCar;
 
            if(isNotValidateArgument(storeId)){
 
                return new CarEntity();
            }
 
 
            storeCar = loadCarById(storeId);
            return storeCar;
 
        } catch (SQLException e) {
            rollback(connection);
            throw new DaoException(MESSAGE_STATEMENT,e);
        } finally {
            ConnectionPool.getPool().closeDbResources(connection, statement);
        }
    }



как избавиться от таких блоков finally ?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.09.2018, 13:58
Ответы с готовыми решениями:

Когда выполнятся .then/catch/finally после того как Promise завершится?
В учебнике написано А что здесь является текущим кодом? Когда витруальная машина начнет выполнять микрозадачи из очереди? Когда...

Как применить свойство hover к элементу списка, когда элемент - ссылка
Добрый день, подскажите пожалуйста, как применить свойство hover к элементу списка, чтобы поменять стиль при наведении на весь элемент? ...

Как можно в textarea применить ::first-line, или как к первой строки применить стиль, внутри данного элемента
Да и вообще, для этого можно ли еще что-либо вложить в данный элемент, кроме как текста? Добавлено через 2 часа 3 минуты вопрос...

12
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2773 / 491
Регистрация: 28.04.2012
Сообщений: 8,760
22.09.2018, 16:19
Цитата Сообщение от masli Посмотреть сообщение
как избавиться от таких блоков finally?
Тебе же уже писали воспользоваться try-with-resources
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
22.09.2018, 19:13  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Тебе же уже писали воспользоваться try-with-resources
Конструкцию try-with-resources ввели в Java 7. Она дает возможность объявлять один или несколько ресурсов в блоке try, которые будут закрыты автоматически без использования finally блока.

В качестве ресурса можно использовать любой объект, класс которого реализует интерфейс java.lang.AutoCloseable или java.io.Closable.

Так как мне поможет здесь конструкция try-with-resources?

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

А как с этим быть.

Java
1
  ConnectionPool.getPool().closeDbResources(connection, statement);
Если знаете скажите, не знаете как, так и скажите...
0
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
22.09.2018, 19:31
Цитата Сообщение от masli Посмотреть сообщение
А как с этим быть.
прочитать как работает try-with-resources и написать соответствующий код?
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2773 / 491
Регистрация: 28.04.2012
Сообщений: 8,760
22.09.2018, 21:10
Цитата Сообщение от masli Посмотреть сообщение
Так как мне поможет здесь конструкция try-with-resources?
Прямо.

Цитата Сообщение от masli Посмотреть сообщение
DataSource не наследует данных классов.
Каких данных классов? И при чём тут вообще DataSource?

Цитата Сообщение от masli Посмотреть сообщение
А как с этим быть.
Это удалить.

Цитата Сообщение от masli Посмотреть сообщение
Если знаете, скажите
Знаю. Тебе уже говорили, и не раз. Даже ссылку на статью с примером дали.
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
27.09.2018, 11:58  [ТС]
Как я и говорил, в данном случае, оператор try-with-resources - не возможно применить.
Для того, чтобы не было подавления исключения, все равно нужно использовать блок try-catch-fynally

Например, вот так:

Кликните здесь для просмотра всего текста
Java
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
    private static OutputStream openOutputStream() throws IOException {
 
        return null;
    }
 
    private static void excCheck(){
 
        OutputStream stream = null;
        Throwable mainException = null;
        try {
            // что-то делаем со stream
            stream = openOutputStream();
        } catch (Throwable t) {
            mainException = t;
            // обрабатываем исключение
        } finally {
 
            try {
                stream.close();
            } catch (Throwable unused) {
                /* игнорируем, так как есть основное исключение
                 можно добавить лог исключения (по желанию)
                Лог создается, если ресурс не закрылся (например, stream = null). 
                Так как закрытие потока невозможно обработать, поэтому нет смысла что-либо
                ловить в данном случае
 
                Throwable unused - подавит вывод исключения (java.lang.NullPointerException) в StackTrace,
                если объект закрываемого
                ресурса равен null*/
            }
        }
    }


Кликните здесь для просмотра всего текста
Java
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
39
 public static void resourcesProcess() {
        OutputStream stream = null;
        Throwable mainException = null;
 
        try {
            /*
            что-то делаем со stream
             */
            String pathToFile = "c:\\driver";
            FileInputStream fileInputStream = new FileInputStream(pathToFile);
            stream = openOutputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
 
            System.out.println("Блок try");
 
        } catch (Throwable t) {
            mainException = t;
            /*
             обрабатываем исключение
              */
            System.out.println("Исключение в блоке catch");
            System.out.println("t = " + mainException);
        } finally {
 
            try {
                stream.close();
            } catch (Throwable unused) {
                System.out.println("++++++++++++++++++++++++++");
                System.out.println("Исключение в блоке finally");
            }
        }
    }
 
 
    private static OutputStream openOutputStream() throws IOException {
 
        return null;
    }


решено
1
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.09.2018, 12:43
Почитайте почему не стоит ловить Throwable. И я бы задумался почему объект закрываем ого ресурса null и надо ли null закрывать.
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
27.09.2018, 13:53  [ТС]
Цитата Сообщение от JIeIIIa Посмотреть сообщение
И я бы задумался почему объект закрываем ого ресурса null и надо ли null закрывать.
Не понял что означает это предложение.

Добавлено через 2 минуты
Если вы имеете ввиду пример выше, то stream = null, это всего лишь имитация того, что возможно в момент попытки закрытия в блоке finally ресурса, он уже к этому моменту будет равен null, либо само закрытие не удастся по каким-то иным причинам.
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.09.2018, 14:02
masli, ок. Объясняте почему в Вашем коде нельзя использовать try-with-resources.
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
27.09.2018, 14:25  [ТС]
Я нашел решение, оно хоть и громоздкое, но можно избежать использование finally.

Кликните здесь для просмотра всего текста
Java
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
@Override
    public List<TranslitEntity> loadAllUserTranslits(Integer userId) {
 
        List<TranslitEntity> result = new ArrayList<TranslitEntity>();
 
        Connection connectionTmp = null;
 
        try (Connection connection = ConnectionPool.getPool().getConnection();
             PreparedStatement statement = connection.prepareStatement("SELECT * from translits " +
                     "WHERE user_id = ?");
 
             ) {
            connectionTmp = connection;
            statement.setInt(1, userId);
 
        try(ResultSet set = statement.executeQuery()){
            System.out.println("set - " + set);
            System.out.println();
            while (set.next()) {
                TranslitEntity entity = ResultSetConverter.createTranslitEntity(set);
                result.add(entity);
            }
        }
 
        } catch (SQLException e) {
            rollback(connectionTmp);
            throw new DaoException(e);
        }
 
        return result;
    }


Как видно, можно было выкрутиться вложенным оператором try-with-resources , а для того, чтобы можно было выполнить откат транзакции, тогда открытый ресурс connection, можно сохранить во временной переменной и ее использовать, чтобы вызвать откат транзакции, на текущем ресурсе.

Добавлено через 2 минуты
Цитата Сообщение от JIeIIIa Посмотреть сообщение
Объясняте почему в Вашем коде нельзя использовать try-with-resources.
Не знал как выполнить откат транзакции и как закрыть ResulSet.
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.09.2018, 14:42
masli, почему не так?
Java
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
public List<TranslitEntity> loadAllUserTranslits(Integer userId) {
 
        List<TranslitEntity> result = new ArrayList<TranslitEntity>();
 
        try (Connection connection = ConnectionPool.getPool().getConnection();
             PreparedStatement statement = connection.prepareStatement("SELECT * from translits " +
                     "WHERE user_id = ?");
        ) {
        
            statement.setInt(1, userId);
 
            try(ResultSet set = statement.executeQuery()){
                System.out.println("set - " + set);   
                System.out.println();
                while (set.next()) {
                    TranslitEntity entity = ResultSetConverter.createTranslitEntity(set);
                    result.add(entity);
                }
            } catch (SQLException e) {
               rollback(connection);
               throw new DaoException(e);
            }
 
        } catch (SQLException e) {
            throw new DaoException(e);
        }
 
        return result;
    }
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
27.09.2018, 14:58  [ТС]
как я понимаю, если исключение "словится" в момент открытия PreparedStatement statement, тогда не нужно будет ничего "откатывать", а вот откат нужен, когда выполняется команда statement.executeQuery() ?

Добавлено через 1 минуту
Таким образом можно избежать использования временной переменной для ресурса connection?
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.09.2018, 14:59
Лучший ответ Сообщение было отмечено masli как решение

Решение

Если не используются вложенные транзакции, то да.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.09.2018, 14:59
Помогаю со студенческими работами здесь

Как быть когда нужно вернуть NULL?
Как быть если нужно чтобы функция в некоторых условиях возвращала NULL, а не возвращаемый тип?

Google Play Services Sign In / com.google.android.gms.common.api.ApiException: 10
Пробую запустить простейший семпл для авторизации в Google Play Services, но всё время получаю одну и ту же ошибку Мой код полностью...

Тип void как возвращаемое значение функции: что он такое, зачем он нужен, где, когда и как его использовать?
Объясните пожалуйста про Void для оооочень далекого человека. Читаю книгу Шилдта, в принципе всё ясно, всё понимаю и пробую, но вот Void -...

Как быть в ситуации когда строка занимает не то место из-за внутреннего идентификатора?
Как быть в ситуации когда строка занимает не то место из-за внутреннего идентификатора? Заранее спасибо!

Когда я закрываю эту форму появляется множество ошибок, как быть?
При Window f = new Window(); f.ShowDialog(); // все хорошо, но 2 формы не могут быть активными при ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru