| /* |
| * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved. |
| * Copyright (c) 2010, 2015 SAP All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Created Oct 1st, 2010 - Adrian Görler, patterned after SybaseTransactionIsolationListener |
| // bug 326777: Some Core LRG tests hang on MaxDB. |
| package org.eclipse.persistence.testing.framework; |
| |
| import java.sql.Connection; |
| import java.sql.SQLException; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor; |
| import org.eclipse.persistence.sessions.SessionEvent; |
| import org.eclipse.persistence.sessions.SessionEventAdapter; |
| |
| /* |
| * <p>SAP MaxDB in general is configured to use transaction isolation level |
| * READ_COMMITTED or SERIALIZABLE.</p> |
| * That causes a few tests to hang, or fail with an error message saying that the table is locked |
| * (depending on a setting on the database side): these tests begin transaction, update a row, |
| * then (before the transaction has been committed) attempt to read the row through another connection. |
| * |
| * To allow these reads to go through (and read the uncommitted data) connection isolation level |
| * should be temporary switched to READ_UNCOMMITTED. |
| * |
| * This class switches the acquired connection to READ_UNCOMMITTED and then sets back the original |
| * isolation level before connection is released. |
| * |
| * Note that for the above scenario only read connections require level READ_UNCOMMITTED. |
| * |
| * @author agoerler |
| */ |
| class JDBCIsoLevelSwitchListener extends SessionEventAdapter { |
| Map<Connection, Integer> connections = new HashMap<Connection, Integer>(); |
| |
| @Override |
| public void postAcquireConnection(SessionEvent event) { |
| Connection conn = ((DatabaseAccessor) event.getResult()).getConnection(); |
| int old; |
| try { |
| old = conn.getTransactionIsolation(); |
| if (old != Connection.TRANSACTION_READ_UNCOMMITTED) { |
| conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); |
| connections.put(conn, old); |
| } |
| } catch (SQLException sqlException) { |
| throw new TestProblemException("postAcquireConnection failed. ", sqlException); |
| } |
| } |
| |
| @Override |
| public void preReleaseConnection(SessionEvent event) { |
| Connection conn = ((DatabaseAccessor) event.getResult()).getConnection(); |
| try { |
| Integer old = connections.remove(conn); |
| if (old != null) { |
| conn.setTransactionIsolation(old); |
| } |
| } catch (SQLException sqlException) { |
| throw new TestProblemException("preReleaseConnection failed. ", sqlException); |
| } |
| } |
| } |