View Javadoc
1   package org.synchronoss.cpo.jdbc;
2   
3   /*-
4    * [[
5    * jdbc
6    * ==
7    * Copyright (C) 2003 - 2026 Exaxis LLC, Synchronoss Technologies Inc
8    * ==
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * ]]
23   */
24  
25  import java.sql.Connection;
26  import java.sql.SQLException;
27  import javax.sql.DataSource;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  import org.synchronoss.cpo.core.CpoException;
31  
32  /**
33   * The default connection strategy: every call-local unit of work checks a connection out of the
34   * read or write datasource and commits/rolls back and returns it when the call completes. If the
35   * read datasource ever fails to produce a connection, the strategy permanently fails over to the
36   * write datasource for reads.
37   *
38   * @author david berry
39   */
40  class JdbcPooledConnectionStrategy implements JdbcConnectionStrategy {
41  
42    /** Version Id for this class. */
43    private static final long serialVersionUID = 1L;
44  
45    private static final Logger logger = LoggerFactory.getLogger(JdbcPooledConnectionStrategy.class);
46  
47    private final transient DataSource readDataSource;
48    private final transient DataSource writeDataSource;
49    private boolean invalidReadDataSource = false;
50  
51    /**
52     * Constructs a JdbcPooledConnectionStrategy
53     *
54     * @param readDataSource The datasource used for read connections
55     * @param writeDataSource The datasource used for write connections
56     */
57    JdbcPooledConnectionStrategy(DataSource readDataSource, DataSource writeDataSource) {
58      this.readDataSource = readDataSource;
59      this.writeDataSource = writeDataSource;
60    }
61  
62    @Override
63    public Connection getReadConnection() throws CpoException {
64      Connection connection;
65  
66      try {
67        if (!invalidReadDataSource) {
68          connection = readDataSource.getConnection();
69        } else {
70          connection = writeDataSource.getConnection();
71        }
72        connection.setAutoCommit(false);
73      } catch (Exception e) {
74        invalidReadDataSource = true;
75  
76        String msg = "getReadConnection(): failed";
77        logger.error(msg, e);
78  
79        try {
80          connection = writeDataSource.getConnection();
81          connection.setAutoCommit(false);
82        } catch (SQLException e2) {
83          msg = "getWriteConnection(): failed";
84          logger.error(msg, e2);
85          throw new CpoException(msg, e2);
86        }
87      }
88  
89      return connection;
90    }
91  
92    @Override
93    public Connection getWriteConnection() throws CpoException {
94      Connection connection;
95  
96      try {
97        connection = writeDataSource.getConnection();
98        connection.setAutoCommit(false);
99      } catch (SQLException e) {
100       String msg = "getWriteConnection(): failed";
101       logger.error(msg, e);
102       throw new CpoException(msg, e);
103     }
104 
105     return connection;
106   }
107 
108   @Override
109   public void closeLocalConnection(Connection connection) {
110     try {
111       if (connection != null && !connection.isClosed()) {
112         connection.close();
113       }
114     } catch (SQLException e) {
115       if (logger.isTraceEnabled()) {
116         logger.trace(e.getMessage());
117       }
118     }
119   }
120 
121   @Override
122   public void commitLocalConnection(Connection connection) {
123     try {
124       if (connection != null) {
125         connection.commit();
126       }
127     } catch (SQLException e) {
128       if (logger.isTraceEnabled()) {
129         logger.trace(e.getMessage());
130       }
131     }
132   }
133 
134   @Override
135   public void rollbackLocalConnection(Connection connection) {
136     try {
137       if (connection != null) {
138         connection.rollback();
139       }
140     } catch (Exception e) {
141       if (logger.isTraceEnabled()) {
142         logger.trace(e.getMessage());
143       }
144     }
145   }
146 }