You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SimpleJDBCConnectionPool.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.data.util.sqlcontainer.connection;
  5. import java.io.IOException;
  6. import java.sql.Connection;
  7. import java.sql.DriverManager;
  8. import java.sql.SQLException;
  9. import java.sql.Statement;
  10. import java.util.HashSet;
  11. import java.util.Set;
  12. /**
  13. * Simple implementation of the JDBCConnectionPool interface. Handles loading
  14. * the JDBC driver, setting up the connections and ensuring they are still
  15. * usable upon release.
  16. */
  17. @SuppressWarnings("serial")
  18. public class SimpleJDBCConnectionPool implements JDBCConnectionPool {
  19. private int initialConnections = 5;
  20. private int maxConnections = 20;
  21. private String driverName;
  22. private String connectionUri;
  23. private String userName;
  24. private String password;
  25. private transient Set<Connection> availableConnections;
  26. private transient Set<Connection> reservedConnections;
  27. private boolean initialized;
  28. public SimpleJDBCConnectionPool(String driverName, String connectionUri,
  29. String userName, String password) throws SQLException {
  30. if (driverName == null) {
  31. throw new IllegalArgumentException(
  32. "JDBC driver class name must be given.");
  33. }
  34. if (connectionUri == null) {
  35. throw new IllegalArgumentException(
  36. "Database connection URI must be given.");
  37. }
  38. if (userName == null) {
  39. throw new IllegalArgumentException(
  40. "Database username must be given.");
  41. }
  42. if (password == null) {
  43. throw new IllegalArgumentException(
  44. "Database password must be given.");
  45. }
  46. this.driverName = driverName;
  47. this.connectionUri = connectionUri;
  48. this.userName = userName;
  49. this.password = password;
  50. /* Initialize JDBC driver */
  51. try {
  52. Class.forName(driverName).newInstance();
  53. } catch (Exception ex) {
  54. throw new RuntimeException("Specified JDBC Driver: " + driverName
  55. + " - initialization failed.", ex);
  56. }
  57. }
  58. public SimpleJDBCConnectionPool(String driverName, String connectionUri,
  59. String userName, String password, int initialConnections,
  60. int maxConnections) throws SQLException {
  61. this(driverName, connectionUri, userName, password);
  62. this.initialConnections = initialConnections;
  63. this.maxConnections = maxConnections;
  64. }
  65. private void initializeConnections() throws SQLException {
  66. availableConnections = new HashSet<Connection>(initialConnections);
  67. reservedConnections = new HashSet<Connection>(initialConnections);
  68. for (int i = 0; i < initialConnections; i++) {
  69. availableConnections.add(createConnection());
  70. }
  71. initialized = true;
  72. }
  73. @Override
  74. public synchronized Connection reserveConnection() throws SQLException {
  75. if (!initialized) {
  76. initializeConnections();
  77. }
  78. if (availableConnections.isEmpty()) {
  79. if (reservedConnections.size() < maxConnections) {
  80. availableConnections.add(createConnection());
  81. } else {
  82. throw new SQLException("Connection limit has been reached.");
  83. }
  84. }
  85. Connection c = availableConnections.iterator().next();
  86. availableConnections.remove(c);
  87. reservedConnections.add(c);
  88. return c;
  89. }
  90. @Override
  91. public synchronized void releaseConnection(Connection conn) {
  92. if (conn == null || !initialized) {
  93. return;
  94. }
  95. /* Try to roll back if necessary */
  96. try {
  97. if (!conn.getAutoCommit()) {
  98. conn.rollback();
  99. }
  100. } catch (SQLException e) {
  101. /* Roll back failed, close and discard connection */
  102. try {
  103. conn.close();
  104. } catch (SQLException e1) {
  105. /* Nothing needs to be done */
  106. }
  107. reservedConnections.remove(conn);
  108. return;
  109. }
  110. reservedConnections.remove(conn);
  111. availableConnections.add(conn);
  112. }
  113. private Connection createConnection() throws SQLException {
  114. Connection c = DriverManager.getConnection(connectionUri, userName,
  115. password);
  116. c.setAutoCommit(false);
  117. if (driverName.toLowerCase().contains("mysql")) {
  118. try {
  119. Statement s = c.createStatement();
  120. s.execute("SET SESSION sql_mode = 'ANSI'");
  121. s.close();
  122. } catch (Exception e) {
  123. // Failed to set ansi mode; continue
  124. }
  125. }
  126. return c;
  127. }
  128. @Override
  129. public void destroy() {
  130. for (Connection c : availableConnections) {
  131. try {
  132. c.close();
  133. } catch (SQLException e) {
  134. // No need to do anything
  135. }
  136. }
  137. for (Connection c : reservedConnections) {
  138. try {
  139. c.close();
  140. } catch (SQLException e) {
  141. // No need to do anything
  142. }
  143. }
  144. }
  145. private void writeObject(java.io.ObjectOutputStream out) throws IOException {
  146. initialized = false;
  147. out.defaultWriteObject();
  148. }
  149. }