I have to extend one of the queries, to join with the table in another database, and possibly another server (linked).
Here are some domain facts, I can't change:
- Weblogic 10 used. EJB2 on the Java side
- Database driver is Non-XA. And we can't change that
- Both of the data sources are set as "Emulate 2 phase commit" transaction
option
- Query that is used is not directly in the business method called by the client, but somewhere in a private method, that is called at some point in the execution.
I am getting the following
java.sql.SQLException: Connection has already been created in this tx
context
for pool named dataSourceA.datasource. Illegal attempt to create
connection from another pool: dataSourceB.datasource
I only need to get the Database name and database host from the data source.
Exceptions comes, when I try to make connection to the data source dataSourceB.
Is there any way to get its properties without making a connection? Just to get String properties, database name and host?
Related
i am running a web app where 3 databases are involved
the first database is the admin database and the two other databases are for two separate institutions,
meaning both institutions are using the same app but can access their separate database per a unique_code entered.
the databases are starter(admin database),company1 and company2.
when the web app is started, the admin database is initially connected to automatically. (starter database).
(first connection pool) code below: which works perfectly.
comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
comboPooledDataSource.setJdbcUrl("jdbc:mysql://host.com/starter");
comboPooledDataSource.setUser("username");
comboPooledDataSource.setPassword("password");
comboPooledDataSource.setMinPoolSize(2);
comboPooledDataSource.setMaxPoolSize(3000);
comboPooledDataSource.setAcquireIncrement(1);
comboPooledDataSource.setMaxIdleTime(1800);
comboPooledDataSource.setMaxStatements(0);
comboPooledDataSource.setIdleConnectionTestPeriod(3);
comboPooledDataSource.setBreakAfterAcquireFailure(false);
comboPooledDataSource.setUnreturnedConnectionTimeout(5);
and the user must enter a code in a textfield on the homepage (like a login).
if the code exist in the starter database, the database related to the code is connected to and the user can view their contents from that database.
//code to fetch database name is written below: which also works successfully
String entry_code=request.getParameter("Ecode");
//where 'Ecode' is the name of the html textfield where the user types the code
try{
con=Main_C3Po_Connection.getInstance().getConnection();
String sql="select db from checker where code='"+entry_code+"'";
pst=con.prepareStatement(sql);
rs=pst.executeQuery();
if(rs.next()){
get_db=rs.getString("db");
}
}catch(SQLException e){
out.println(e);
}
eg: starter(admin database)
table name : checker
id | code | db |
11 | 44 | company1 |
12 | 35 | company2 |
so the second connection pool doesnt have a fixed database url but a variable database name.
eg:("jdbc:mysql://host.com/"+get_db+"?autoReconnect=true&useUnicode=yes");
where get_db is the variable name.
so when the user enters code 44, the value in the db column relating to the code entered is (company1), is then placed into the get_db variable and the database is connected to and can be accessed.
when the first code(44) is entered, the 'company1' value is placed into the 'get_db' variable and the connection is made successfully.
but the problem is after logging out and the second code (35) is entered, the 'company2' value is also placed into the 'get_db' variable BUT
the connection pool for some reason still keeps the previous database connection and cannot switch to the other database chosen.
below is the second connection pool which cannot switch to a different database, though the database variable is changed:
comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
comboPooledDataSource.setJdbcUrl("jdbc:mysql://host.com/"+get_db+"?autoReconnect=true&useUnicode=yes");
comboPooledDataSource.setUser("username");
comboPooledDataSource.setPassword("password");
comboPooledDataSource.setMinPoolSize(2);
comboPooledDataSource.setMaxPoolSize(3000);
comboPooledDataSource.setAcquireIncrement(1);
comboPooledDataSource.setMaxIdleTime(1800);
comboPooledDataSource.setMaxStatements(0);
comboPooledDataSource.setIdleConnectionTestPeriod(5);
comboPooledDataSource.setBreakAfterAcquireFailure(false);
comboPooledDataSource.setUnreturnedConnectionTimeout(5);
please how do i configure the second connection pool to kill all connections after logging out so that it can **switch** and access any other database chosen. thank you.
This is an awkward configuration; I don't recommend it. But it should work. The act of calling
comboPooledDataSource.setJdbcUrl("jdbc:mysql://host.com/"+get_db+"?autoReconnect=true&useUnicode=yes");
should cause a "soft reset", so any new Connections you get from the pool will be to the new DB. Are you sure that you are not still using the old Connection? That is, have you been sure to close() all Connection objects from before the change?
A less awkward approach would just be to make multiple Connection pools, one for each database you need to access. When you are done with a Connection pool, free the threads and Connections associated with it by calling close() on the pool itself.
When I run all my JUnit tests, which uses a MS SQL Server database, I'm getting the following error:
java.sql.SQLException: Could not find database ID X, name 'database_name'. The database may be offline. Wait a few minutes and try again.
or sometimes the java.sql.Connection object is closed unexpectedly.
I got rid of the problem when I turned AUTO CLOSE setting to OFF, right after database creation:
CREATE DATABASE TEST123;
ALTER DATABASE [TEST123] SET AUTO_CLOSE OFF WITH NO_WAIT;
Check it out: Worst Practice: Allowing AutoClose on SQL Server Databases
I'm writing a program that does some stuff on the database. Users are allowed to configure db processes, by passing db host port, type and credentials. It all works fine when values are correct. But when user passes invalid credentials I would like to show an error. So here is the part where I create my connection pool
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setJdbcUrl( connectionUrl );
cpds.setUser(username);
cpds.setPassword(password);
And later to verify if all is ok with the connection I do
cpds.getConnection()
I would expect to get some SQLException with vendor specific error saying that credentials are invalid (which happens when you use typical DriverManager way of getting the connection), but instead the process waits until a connection checkout exception is thrown
java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:118)
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:77)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:690)
....
Caused by: com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool#20014b8 -- timeout at awaitAvailable()
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1467)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:644)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:554)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:758)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:685)
... 66 more
How can I identify that there is a invalid credential issue with c3p0?
Your best way to validate provided credentials/JDBC params is to avoid connection pool at all.
Open dedicated connection just for this purpose and try to execute simplest SQL against new connection (eg SELECT 1 or similar).
After success, you can pass them to C3P0 otherwise propagate error back to user.
JDBC providers are free to create whatever error/exception messages they want. So you need to be ready to parse the error message of each provider in order to make sense of what is happening.
You can also try to get information from exception types if the JDBC provider segregates errors in separate types.
As a side note, giving too much information regarding why the connection failed may be considered a security breach. So one should not expect the JDBC driver to give you such information. For instance, why would any database collaborate with invasion attempts by saying "the username is correct, but the password is not."?
I have Java application with Hibernate framework(no spring) connect to MySQL DB , manage connection pooling via c3p0
i try to configure my apllication to read from slave db and write to master db , i have following this link to some extend Master/Slave load balance
let's say if the application already got a session with connection in pool and it need to execute a read-only method , like this
public someReadOnlyMethod()
{
Session session = (get session from current Thread)
//set read-only so that it read from slave db
session.connection().setReadOnly(true);
(...connect to db to do something...)
//set it back in case of this method is followed by write method so that it go to master db
session.connection().setReadOnly(false);
}
Is the pooling create a new connection to connect to db 2 times for read-only and write operation(if so,this will heavily impact performance) or it smart enough to swap the operation to already existing read-only and writable connection pool ?
thx for your advice.
so this has nothing to do with the pool; it's all in the mysql driver. c3p0 will pass your call to setReadOnly (whether true or false) to the underlying Connection, and the Connection will route to the master or the slaves accordingly.
if you don't like how your Connections default (probably by default they are not read only), you can set the read-only property in the onAcquire method of a c3p0 ConnectionCustomizer, and the value use set (true or false) will become th default that c3p0 resets Connections to.
good luck!
tl;dr: It will re-use existing connections whenever you switch setReadOnly(true/false).
JDBC will connect to all servers listed in your connection URL when you do ReplicationDriver().connect(url). Those connections will remain open for re-use no matter how many times you switch setReadOnly().
Source: I just tested Connector/J version 5.1.38 with com.mysql.jdbc.ReplicationDriver.
I am trying to connect to MSSQL server 2008 on my localhost, but I am getting Errors
WARNING: ConnectionID:2 Prelogin error: host 127.0.0.1 port 1434 Error reading prelogin response: Connection reset
this error repeats like 20 times very quickly, then i get
com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset
I suspect this is some wrong configuration of server. I can connect to external servers with no issues. I can also connect via management studio with no problems.
Please help me, I am getting sick of this issue :|
1) TCP protocol for MSSQL 2008 is disabled by default. You need to enable it from SQL Configuration Manager (in the same [Start], Programs folder as MSSQL):
http://msdn.microsoft.com/en-us/library/ms190425%28v=sql.105%29.aspx
2) To use TCP connections (even on localhost!) you need to allow MSSQL in Windows Firewall:
http://technet.microsoft.com/en-us/library/cc646023.aspx
3) You don't necessarily need to use TCP/IP in order to access MSSQL:
http://msdn.microsoft.com/en-us/library/ms187892%28v=sql.105%29.aspx
'Hope that helps!
To connect to MSSQL Server from a Java application, you need to use the JDBC API. The JDBC API provides classes and methods that connect to the database, load the appropriate driver, send SQL queries, retrieve results etc.
HOW TO CONNECT TO THE DATABASE A ‘Connection’ object represents a connection with a database. To establish the connection, use the method ‘DriverManager.getConnection’. This method takes a string containing a URL which represents the database we are trying to connect to. Below is the sample code for establishing a connection:
private String DATABASE_URL = "jdbc:odbc:embedded_sql_app"; // establish connection to database
Connection connection = DriverManager.getConnection( DATABASE_URL,"sa","123" );
Detailed discussion about the Database URL and how to create it can be found in the resource provided at the end of this post.
QUERYING THE DATABASE The JDBC API provides three interfaces for sending SQL statements to the database, and corresponding methods in the ‘Connection’ interface create instances of them. 1. Statement - created by the ‘Connection.createStatement’ methods. A ‘Statement’ object is used for sending SQL statements with no parameters.
2. PreparedStatement - created by the ‘Connection.prepareStatement methods’. A ‘PreparedStatement’ object is used for precompiled SQL statements. These can take one or more parameters as input arguments (IN parameters).
3. CallableStatement - created by the ‘Connection.prepareCall’ methods. ‘CallableStatement’ objects are used to execute SQL stored procedures from Java database applications.
RETRIEVING THE RESULT A ‘ResultSet ‘is a Java object that contains the results of executing a SQL query. The data stored in a ‘ResultSet’ object is retrieved through a set of get methods that allows access to the various columns of the current row. The ‘ResultSet.next’ method is used to move to the next row of the ‘ResultSet’, making it the current row. The following code fragment executes a query that returns a collection of rows, with column ‘a’ as an ‘int’, column ‘b’ as a ‘String’, and column ‘c’ as a ‘float’:
java.sql.Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next()) { // retrieve and print the values for the current row
int i = rs.getInt("a");
String s = rs.getString("b");
float f = rs.getFloat("c");
System.out.println("ROW = " + i + " " + s + " " + f); }
This is just a brief introduction on how to interact with a database from Java. For more details on the items discussed above as well as information on passing parameters, executing stored procedures etc. please refer to the following resource: ( http://www.shahriarnk.com/Shahriar-N-K-Research-Embedding-SQL-in-C-Sharp-Java.html#Shahriar_N_Embedding_SQL_in_Java ) Here, you will also find information on how to interact with a database programmatically; i.e. without using SQL. Hope you find this useful.