java.sql.SQLException: Could not find database ID X name 'database'. - java

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

Related

c3p0 connection pool cannot change database

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.

Understanding JDBC Timeout Variables and replication

I am using JDBC driver to connect to mySql from my java code (read client).
Driver = com.mysql.jdbc.Driver
JdbcUrl = jdbc:mysql://<<IpOftheDb>>/<<DbSchema Name>>?autoReconnect=true&connectTimeout=5000&socketTimeout=10000
In case the database is down ( machine hosting the db is up but the mysqld process is not running) , it takes some time to get the exception , The exception is
"com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:Could not create connection to database server. Attempted reconnect 3 times. Giving up."
In the statement above socketTimeout is 10 sec . Now if I bring up the db with 10 sec as SocketTimeout I get the response correctly.
But If i reduce it to one sec and am executing the query I get the same exception.
"com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:Could not create connection to database server. Attempted reconnect 3 times. Giving up."
But connectTimeout doesnt change anything. Can someone explain me what socketTimeout and connectTimeout means.
Also , If we are setting up replication and specifying the 2nd database as failover i.e.
my connection string changes to
jdbc:mysql://<<PrimaryDbIP>>,<<SecondaryDbIp>>/<<DbSchema>>?useTimezone=true
&serverTimezone=UTC&useLegacyDatetimeCode=false
&failOverReadOnly=false&autoReconnect=true&maxReconnects=3
&initialTimeout=5000&connectTimeout=6000&socketTimeout=6000
&queriesBeforeRetryMaster=50&secondsBeforeRetryMaster=30
I see that if primary is down then I get the response from secondary (failover Db) .
Now when client executes a query , does it go to primary database and then wait for socketTimeout (or whatever) and then goes to Secondary or it goes to Seconday before timeout occurs.
Moreover, the second time when the same connection Object is used , does it go directly to the secondary or again the above process is repeated .
I tried find some documentation which explains this but couldnt get .
Hopefully , someone can help here explaining the various timeout parameters and their usefulness.

How to differ between MSSQL JDBC error codes?

My server calls sometimes the MSSQL JDBC CallableStatement.execute() that works with a previously connected connection. Everything is ok while the connection is alive. But if the connection is disconnected somehow (e.g. somebody turn SQL server down) the execute() call throws SQLException. I need to differ between 'connection was dropped' error and any other JDBC error (like table I'm trying to use doesn't exist). Since if I hit the connection error - I need to reconnect. And in any other case I need just to give error message to the user.
SQLException.getSQLState() always returns null and getErrorCode() always returns 0.
Thanks
I am no Java expert but this seems to be mainly based on Java.
You'd need to catch the exception from the .execute() command and query the string to see what the error is, then make a decision on which method to execute next based on that information.

IJ000453: Unable to get managed connection

I got the following error when I have tried to hit DB for more than the number of max pool size.
ERROR: javax.resource.ResourceException: IJ000453: Unable to get managed connection.
Fetching data is working properly but when i try to save data through stored procedure, i'm facing issue.To invoke procedure we are using prepare statement. I closed the connections properly. I don't know whether the connection is returned to the pool or not?

Copying table to different database in MSSQL

I have condition where there are some table from one database (in mssql) which will be copied into another database. The copying time must be when a specific time, which will be given from application. In my case, I use Java programming. Is there any easiest way to do that?
Create a SQL Agent Job in MS SQL Server that copies your data from one database to the other. Then in your Java app connect to the MS SQL Server and start the SQL Server Agent Job.
Connection rConn = //Your Connection details
CallableStatement cs = rConn.prepareCall("EXECUTE dbo.sp_start_job N'your job name'");
boolean checkvar = cs.execute();
You will need to connect to the MSDB database and the account you connect with needs to be in the sysadmin role or the SQLAgentOperatorRole
You SQL statement in your job may look something like this:
INSERT INTO DestinationDatabseName.dbo.DestinationTable (ColumnNames)
SELECT YourColumns
FROM SourceDatabaseName.dbo.SourceTable

Categories