Соединение недоступно при вызове метода createOrWaitForConnection для ресурса? - PullRequest
0 голосов
/ 12 февраля 2019

Приложение для spring4 + jaxb + jpa deployd на websphere 8.5.5.13 и oracle11g

Иногда я вижу ссылку на сообщение об ошибке с максимальным размером пула соединений:

Соединение недоступно, покавызов метода createOrWaitForConnection для ресурса

Итак, как правильно его исправить 1. Просто увеличьте размер подключений к пулу до 50 2. Рефакторинг кода

Вы видите некоторые незакрытые подключения в моемкод, есть ли грубая ошибка при использовании JPA?

мой сервис:

@Service
public class UserService {
    @Autowired
    private UserRepository repository;
    @Autowired
    private EntityManagerFactory entityManagerFactory;
    private Logger logger = Logger.getLogger(UserService.class);


    public List<User> find(String name, String surname, List<String> types) throws Exception {
        logger.log(Level.INFO, "UserService.find()[find by params..]");
        Assert.isTrue(name != null || surname != null,
                "Один из параметров name или surname обязательны для получения риск-метрики");

        List<UserRecord> UserRecords = new ArrayList<>();
        if (CollectionUtils.isEmpty(types)) {
            UserRecords.addAll(find(name, surname));
        } else {
            types.stream().forEach(type -> UserRecords.addAll(find(name, surname, type)));
        }

        return extractUsers(UserRecords);
    }

    public List<User> find(String id) {
        logger.log(Level.INFO, "UserService.find()[find by id]");
        UserRecord UserRecord = repository.findOne(id);
        if (UserRecord == null) return Collections.emptyList();

        User User = (User) deserialize(UserRecord.getUser());
        User.setVersion(UserRecord.getVersion());
        User.setObjectId(UserRecord.getPrKey());

        return Collections.singletonList(User);
    }

    private List<User> extractUsers(List<UserRecord> UserRecords) {
        logger.log(Level.INFO, "UserService.extractUsers()");
        if (CollectionUtils.isEmpty(UserRecords) || UserRecords.stream().allMatch(x -> x == null)) {
            return new ArrayList<>();
        }

        return UserRecords.stream().map(UserRecord -> {
            User User = (User) deserialize(UserRecord.getUser());
            User.setVersion(UserRecord.getVersion());
            User.setObjectId(UserRecord.getPrKey());
            return User;
        }).collect(Collectors.toList());
    }

    private List<UserRecord> find(String name, String surname, String UserType) {
        List<UserRecord> UserRecords;
        if (name != null && surname != null) {
            UserRecords = repository.findUserRecordsByNameAndSurnameAndUserType(name, surname, UserType);
        } else {
            if (name == null) {
                UserRecords = repository.findUserRecordsBySurnameAndUserType(surname, UserType);
            } else {
                UserRecords = repository.findUserRecordsByNameAndUserType(name, UserType);
            }
        }

        return UserRecords.stream().allMatch(x -> x == null) ? new ArrayList<>() : UserRecords;
    }

    private List<UserRecord> find(String name, String surname) {
        List<UserRecord> UserRecords;
        if (name != null && surname != null) {
            UserRecords = repository.findUserRecordsByNameAndSurname(name, surname);
        } else {
            if (name == null) {
                UserRecords = repository.findUserRecordsBySurname(surname);
            } else {
                UserRecords = repository.findUserRecordsByName(name);
            }
        }

        return UserRecords;
    }
}

class UserComparator implements Comparator<User> {
    @Override
    public int compare(User o1, User o2) {
        return Integer.compare(o1.getVersion(), o2.getVersion());
    }
}

Мой объект Jpa:

@Entity
@Audited
@Table(name = "userRecord", uniqueConstraints = {
        @UniqueConstraint(columnNames = {"name", "surname", "userType", "idCalc"})})
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@AllArgsConstructor
@Getter
@Setter
@Access(AccessType.FIELD)
public class userRecord {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(name = "PR_KEY")
    private String prKey;

    //Business Key
    @Column(name = "name", length = 100, unique = false)
    private String name;

    //Business Key
    @Column(name = "surname", length = 100, nullable = false)
    private String surname;

    //Business Key
    @Column(name = "userType", length = 100, nullable = false)
    private String userType;

    //Business Key
    @Column(name = "idCalc", length = 64, nullable = false)
    private String idCalc;

    @Version
    private int version;

    @Column(name = "user", length = 100000)
    @Lob
    private byte[] user;

    public userRecord(String name, String surname, String userType, byte[] user) {
        this.name = name;
        this.surname = surname;
        this.userType = userType;
        this.user = user;
    }

    public userRecord(String name, String surname, String userType,
                            String idCalc, byte[] user) {
        this.name = name;
        this.surname = surname;
        this.userType = userType;
        this.user = user;
        this.idCalc = idCalc;
    }
}

Мой репозиторий:

@Repository
public interface RickMetricRepository extends CrudRepository<userRecord, String> {
    List<userRecord> finduserRecordsBynameAndsurnameAnduserType(
            String name, String surname, String userType);

    userRecord finduserRecordBynameAndsurnameAnduserTypeAndIdCalc(
            String name, String surname, String userType, String idCalc);

    List<userRecord> finduserRecordsBynameAndsurname(String name, String surname);

    List<userRecord> finduserRecordsBysurname(String surname);

    List<userRecord> finduserRecordsBysurnameAnduserType(String surname, String userType);

    List<userRecord> finduserRecordsBynameAnduserType(String name, String userType);

    List<userRecord> finduserRecordsByname(String name);

    userRecord finduserRecordByPrKey(String id);
}

Нужны ли некоторые операции ЗАКРЫТЬ ПОДКЛЮЧЕНИЕ?

1 Ответ

0 голосов
/ 12 февраля 2019

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

Эта проблема в основном возникает во время развертывания нового приложения, когда приложение не закрывает соединение или когда происходит утечка соединения.Каждое соединение должно быть в этом шаблоне: Get / Use / Close

Когда вы видите этот тип ошибок в трассировках для новых приложений, самое первое, что нужно проверить, это шаблон кода соединения в новом приложении.Это должно следовать за подключением get-use-close.Каждое соединение должно быть правильно закрыто, тогда только соединение возвращается в пул, и оно готово к использованию для следующего вызова getConnection.Если приложение не закрывает соединение и не завершает соединения, то новые getConnection запросы не смогут получить соединение с интервалом ConnectionWaitTimeout.

Вы можете получить дополнительную информацию здесь .

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