2015-10-07 2 views
1

Использование Glassfish 4.1, Eclipselink 2.5.1, Oracle 11g.Аутентификация прокси-сервера Oracle: откат всей транзакции

У нас возникли проблемы с откатом изменений при сохранении отношения «один ко многим» (родительские дети) с использованием Аутентификация прокси-сервера Oracle. Если какое-либо исключение возникает при сохранении одного из дочерних элементов, родительский объект по-прежнему сохраняется в БД (не откатывается, как ожидалось). Мы экономим к БД из безгосударственного EJB с управляемой контейнером JTA EntityManager с:

entitymanager.persist(parent); 

cascade = CascadeType.ALL используется на отношения на материнской стороне.

Наш persistence.xml содержит <persistence-unit name="admin_war_1.0-SNAPSHOTPU" transaction-type="JTA">, и проблема в том, что у нас есть только один слой с сохранением (пока все работает нормально).

Родитель объект является чем-то вроде:

public class KornstoranalyseStd implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Basic(optional = false) 
    @Column(name = "KORNSTORANALYSE_STD_ID", nullable = false) 
    private Integer kornstoranalyseStdId; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "kornstoranalyseStd", fetch = FetchType.EAGER) 
    @OrderBy("maskestoerrelse DESC") 
    private Collection<KornstoranalyseStdSigte> kornstoranalyseStdSigteCollection; 
} 

И ребенок юридическое лицо:

public class KornstoranalyseStdSigte implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @Basic(optional = false) 
    @Column(name = "KORNSTORANALYSE_STD_SIGTE_ID", nullable = false) 
    private Integer kornstoranalyseStdSigteId; 

    @Basic(optional = false) 
    @NotNull 
    @Column(name = "MASKESTOERRELSE", nullable = false, precision = 12, scale = 8) 
    private BigDecimal maskestoerrelse; 

    @JoinColumn(name = "KORNSTORANALYSE_STD_ID", referencedColumnName = "KORNSTORANALYSE_STD_ID", nullable = false) 
    @ManyToOne(optional = false, fetch = FetchType.EAGER) 
    private KornstoranalyseStd kornstoranalyseStd; 
} 

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

KornstoranalyseStd parent = new KornstoranalyseStd(); 
    parent.setKornstoranalyseStdId(1); 
    List<KornstoranalyseStdSigte> children = new ArrayList<>(); 
    KornstoranalyseStdSigte child = new KornstoranalyseStdSigte(); 
    child.setKornstoranalyseStdSigteId(1); 
    child.setMaskestoerrelse(new BigDecimal(11)); 
    child.setKornstoranalyseStd(parent); 
    children.add(child); 
    parent.setKornstoranalyseStdSigteCollection(children); 
    getEjbFacade().create(parent); 

Это СЦБ :

@Stateless 
public class KornstoranalyseStdFacade { 
    @PersistenceContext(unitName = "admin_war_1.0-SNAPSHOTPU") 
    private EntityManager em; 

    private EntityManager getEntityManager() { 
     return em; 
    } 

    public void create(KornstoranalyseStd entity) { 
     getEntityManager().persist(entity); 
    } 
} 

Во всех вызовов через EJB, мы прокси в EntityManager с

 getEntityManager().setProperty("eclipselink.oracle.proxy-type", 1); 
     getEntityManager().setProperty("PROXY_USER_NAME", loginBean.getUsername()); 
     getEntityManager().setProperty("PROXY_USER_PASSWORD", loginBean.getPassword()); 
     getEntityManager().setProperty("eclipselink.jdbc.exclusive-connection.mode", "Always"); 
     getEntityManager().setProperty("eclipselink.jdbc.exclusive-connection.is-lazy", "true"); 

Вышеуказанные линии в @AroundInvoke-method, и, следовательно, не будет работать независимо от того, что EJB-метод доступен.

Проблема возникает только при проксировании, а не при опускании этой части. Похоже, проблема связана с подключением jdbc-соединений. Мы пробовали все виды параметров в пуле соединений Glassfish; relaxAutoCommit = true, AutoCommit = false и т. д., но ничего не изменилось.

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

+1

Вы не указали демаркацию транзакции, определение источника данных или само исключение, поэтому мы не можем понять, в чем проблема. Я предполагаю, что вы не настроили источник данных JTA в стеклянной платке, так что EclipseLink пишет через соединение за пределами транзакции, в результате чего каждый оператор автоматически настраивается. – Chris

+0

Большое спасибо Крис - вы правы, я пропустил многое для краткости. Демаркация дается с использованием CMT в STSB, не так ли? Извините, я не указал прямо. Что-то особенное необходимо для источника данных JTA в GF (у нас есть «стандартный» источник данных/пул соединений)? Тем не менее, похоже, проблема заключалась в аутентификации Oracle proxy, что было еще одним пропуском для простоты. Как вы говорите, похоже, соединение за пределами транзакции. Удалит вопрос, если подтвердится. Спасибо за комментарий снова –

ответ

0

Быстрое решение кажется:

  • Конец EJB-метод с em.flush();

Это сделает родительский откат тоже - не спрашивайте меня, почему.

Обратите внимание, что исключение, возникающее при сбое дочернего объекта, будет иным (e.getCause() будет другим, в случае, если вы укажете enduser, но оно все равно будет завернуто в исключение EJBException).

Другим решением является:

  • Использование RESOURCE_LOCAL и не JTA-источников данных, как написано в другом ответе. Вам нужно будет ввести EntityManagerFactory в EJB и обработать транзакцию самостоятельно.

Я не нашел способ сконфигурировать меня.

1

У меня была схожая проблема при использовании entitymanager с datsource, определенным на сервере приложений. Для решения этой проблемы я сделал это:

1- я установить транзакции типа = «RESOURCE_LOCAL» в persistence.xml и определения персистентности-блок

2- я не-JTA-данных источника собственности с значение myDatasourceName

Я понял, что корень исключения jta!

+0

Вы тоже используете аутентификацию прокси-сервера oracle, @Abbas? –

Смежные вопросы