how to change datasource connection url dynamically in Jboss 6 - java

I am using Jboss AS6 with container manager tracsaction.
Normally I am using a single MYSQL data source defined in mysql-ds.xml.
Now I have an user requirement that multiple users can have different database contents.So I am planning to create a new database for each user.In the future I can change my database design. But now for a quick solution, I need to find a way to crossover between different databases.
this is my default configuration. I need to change dbname
<local-tx-datasource>
<jndi-name>DefaultDS</jndi-name>
<connection-url>jdbc:mysql://144.0.0.1:3306/**dbname**</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>password</password>
<max-pool-size>100</max-pool-size>
<min-pool-size>0</min-pool-size>
<connection-property name="readOnly">false</connection-property>
<autoReconnect>true</autoReconnect>
<failOverReadOnly>false</failOverReadOnly>
<maxReconnects>0</maxReconnects>
<initialTimeout>15</initialTimeout>
<idle-timeout-minutes>0</idle-timeout-minutes>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<!-- should only be used on drivers after 3.22.1 with "ping" support
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
-->
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-sql>
-->
<!-- sql to call on an existing pooled connection when it is obtained from pool - MySQLValidConnectionChecker is preferred for newer drivers
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
-->
</local-tx-datasource>
I am using Container manager transcaction.I need to find a way to change connection-url of my data source configuration.Then clear entity manager to connect new database.Is this possible

For your task you actually can just hold multiple (5 in your case) persistence contexts. Then you link to appropriate context by choosing it according to the user name for example. This is the simpliest solution. It would work but all 5 contexts would be open and hold connection. Maybe it's what you need: from one hand this context are always ready for use and don't need to be warmed.
Another option is to construct persistence conext manually like in Java SE envirionment. This can be helpful if you are not able to hold many resources and switching is not so regular (once a day. for example).
You can find a lot of articles describing how to use JPA in Java SE environment. You are able to use them nearly in the same manner (so you will not use container injection mechanism, but find Persistnece Context through raw JNDI)
https://dzone.com/articles/jpa-tutorial-setting-jpa-java
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/SettingUpJPA/SettingUpJPA.htm

I think you could use something like:
<connection-url>${connectionURL:jdbc:mysql://144.0.0.1:3306/xyz}</connection-url>
and then pas the -DconnectionURL=jdbc:mysql://144.0.0.1:3306/abc to the standalone.sh/bat

Related

Multiple Data sources for C3P0

I am developing a tool that receives different connection parameters to test values in different databases (a plugin for Nagios in jNRPE that keeps an open connection to different databases).
Because the configuration is dynamic (there could be more databases or they can be removed) I cannot have a configuration file.
I want to know if I should have an instance of C3P0 per database or can I use the same instance and just change the URL each time I ask for a connection?
The code is at github:
https://github.com/angoca/db2-jnrpe/blob/master/src/main/java/com/github/angoca/db2_jnrpe/database/pools/c3p0/DBCP_c3p0.java
If not, how can I get multiple pool for multiple databases dynamically?
You'll need a different c3p0 DataSource for each JDBC url. A Connection pool must contain homogeneous Connections: all checked out Connections must be equivalent from a client's perspective. If Connections from multiple databases were included in the same pool, clients would have no way of specifying or knowing which db they were communicating with.
(If you are replicating, say, a read-only DB and you really want Connections from multiple sources to live in a single pool, because they are guaranteed to be equivalent from a client's point of view, you could do that by defining a custom, unpooled DataSource that round-robined or randomly chose a replicant, and then pooling the DataSource via c3p0's DataSources factory.)
It is very easy to dynamically create and configure c3p0 DataSources. See example code here.
If you capture your dynamic config as a map of c3p0 property names to values, there's also an alternative, more concise way to get a DataSource with that configuration.

Java - DBCP vs JNDI?

I am a newbie and I have created a few simlpe Java Swing applications. I was able to use apache commons DBCP to create a connection pool and access the datasource.
I have recently started to create java web based applciations using JSP and Servlets. I have learnt to use JNDI to access the datasource. I update the XML files and use InitialContext() and lookup("java:comp/env") and that is it!!!! I am using Apache Tomcat as my Servlet/JSP container.
1. But where is the DB connection pool created?
2. If yes, then does that mean JNDI somehow uses the DBCP internally?
When I have to create a DBCP for Swing applications, I had to first create an instance of GenericObjectPool and then create a connection factory object and finally a PoolableConnectionFactory object to create the Datasource which will be used to get a connection.
JNDI is a mechanism to pass objects from one part of the system to another (in technical terms across class loaders). This is most useful for classes and interfaces found in the Java Runtime like String or DataSource.
This means that in your case JNDI is just a transport mechanism and you need to have the actual connection pool defined elsewhere. Most web containers have a mechanism for defining a system wide connection pool, and JNDI then allows you to get to it.
Tomcat use a custom implementation of Apache DBCP and Apache Pool for the JNDI Datasource. These libraries are located in a single JAR at $CATALINA_HOME/lib/tomcat-dbcp.jar.
The main package is org.apache.tomcat.dbcp for avoid conflicts with the regular packages form Apache Commons.
JNDI is a mechanism of locating remote resources via lookup. It has nothing in common with connection pooling libraries. These libraries, of which c3p0, DBCP and BoneCP, are the most famous, allow you to create data sources with ability to pool connections and/or statements. If this data source is used within your application, you don't need to use JNDI, if it is located on a remote system (for instance, in Tomcat), you need to use JNDI to get access to the data source.
As a side note, why did you choose to work with old-school Servlet/JSP combo? It is a better idea to work with JSP successor, facelets that is a preferred view technology in JSF 2.x.
Another comment is to transfer management of your data source to a well-known framework. One direction might be to use an ORM, for example, Hibernate, to manage your data source (which was created with connection pooling in mind).

Is there any performance difference between these two JDBC Connectivity?

I have used MySqlDataSource for in jdbc connectivity.I have used following code
MysqlDataSource d = new MysqlDataSource();
d.setUser("user");
d.setPassword("pass");
d.setServerName("hostname.com");
d.setDatabaseName("db");
Connection c = d.getConnection();
Also i have searched there is an option of Configuring a MySQL Datasource in Apache Tomcat.
Is there any performance difference between these two? which one is best to use?
Configuring Datasource in tomcat will help you to share same data source between applications running in same tomcat. that Datasource will be managed by container (tomcat in your case).
while the Datasource created in code will be created by your application and can be used by that application only.
So if you have multiple application running on tomcat and accessing same data source, that configuring Datasource in tomcat will be good approach and have performance factor because only one data source is created and not having separate connections for each application
But if you have only single application that the first approach you have used is good one
They both use the internally the same driver, i dont think the performance is much different here, i guess if you need to access teh database only at that place and the enduser isn't supposed to use his own authentication you may use it directly from java, but if you will need the connectivity on different places it could be helpful to configure this using apache configuration, specially that if anything changes like database server, user name or whatever you don't need to get in the code to change it, this could be very important if end users have to set their own configurations.
The improvement of configuring a pool of Connections (as the one provided by tomcat) is mainly that you will actually create and close a lot less of connections.
When using a pool, when you request a Connection to a pool it will look if it has any connection already created and available for reuse and, if it has, it will provide you with it (instead of creating a new Connection, which is a heavy operation). You must still close() a Connection provided by Tomcat so Tomcat knows that it can now reuse when it is requested again.
Additionally, the advantage of the pool is that your code does not need to know the configuration data for the Connection. He just requests a Connection from a given pool and the sysadmin configures it, allowing for greater flexibility (the sysadmin does not need to know how to configure your app, just how to configure the Tomcat which is fairly more standard).

Can the application change the isolation level on each individual transaction on the WebSphere and DB2 combination

I have a an appliction running on the WebSphere application server (7.0.0.19), using DB2 database (9.5). I have the impression that the application server or the database ignores the isolation level which is set in the application (in the Java code). The application uses gets the connections from the application server, it uses the transaction manager from the application server.
I did not find a clear answer (or acknowledgement), not in the manuals, not on the web. I found some indications, suggestions, insinuations, but no clear answers. Some monitoring on the database seams to prove this.
Can someone acknowledge this behaviour?
Can this be changed using configuration?
Since the data source is managed by the application server (and WebSphere is a full featured implementation of Java EE), it's actually the JCA spec that applies here. Section 7.9 of the JCA 1.5 imposes the following restrictions on the ability of an application to change the transaction isolation level:
If a connection is marked as shareable, it must be transparent to the application whether a single shared connection is used or not. The application must not make assumptions about a single shared connection being used, and hence must use the connection in a shareable manner.
However, a J2EE application component that intends to use a connection in an unshareable way must leave a deployment hint to that effect, which will prevent the connection from being shared by the container. Examples of unshareable usage of a connection include changing the security attributes, isolation levels, character settings, and localization configuration.
To summarize: in general, your application should not attempt to change the isolation level if the resource reference configures the connection as shareable. If you look at the Requirements for setting data access isolation levels topic in the WAS infocenter, you will also find the following statement:
Trying to directly set the isolation level through the setTransactionIsolation() method on a shareable connection that runs in a global transaction is not allowed. To use a different isolation level on connections, you must provide a different resource reference.
On the other hand, section 7.9.1 of the JCA 1.5 spec describes scenarios where an app server may still allow an application to change the isolation level, even if the connection is shareable. Basically this applies to scenarios where the connection is configured as shareable, but where it is effectively not shared (because there is no need to share the connection between multiple components).
The Extensions to data access APIs topic in the infocenter suggests that WebSphere supports this:
applications [...] cannot modify the properties of a shareable connection after making the connection request, if other handles exist for that connection. (If no other handles are associated with the connection, then the connection properties can be altered.)
Therefore you should be able to use setTransactionIsolation() to change the isolation level in particular scenarios, but this depends on how your application uses the connection.
Finally, you didn't describe in detail how you monitored that at the database level, but you need to take into account that at some point the app server needs to reset the isolation level on the physical connection. Therefore, if setTransactionIsolation() succeeds, the change may be in effect only for a short time on the physical connection.
Note that there are a couple of ways to avoid all these complications (that may or may not be applicable in your case):
Instead of using setTransactionIsolation(), configure the appropriate isolation level on the resource reference, and if necessary use multiple resource references.
Use the WebSphere specific WSDataSource API to specify the expected isolation level before acquiring the connection.
Modify your SQL to change the isolation level on a per query basis (e.g. use WITH UR).
http://www.ibm.com/developerworks/java/library/j-isolation/index.html this is relevant
also ejb transactions and isolation level discussion applies
http://java.boot.by/ibm-287/ch05.html

How can I store sensitive data in Java configuration files?

I have some code that I want to make public. The code sends email via servers, connects to databases, and other tasks requiring usernames/passwords.
I'd like to store the passwords and such in a seperate configuration file so that I don't have to sanitize my code on every commit.
How can I do this? It would be easy to do in C using #define, but I'm not sure how to accomplish this in Java.
EDIT: The environment I'm using is Glassfish
The basic method is put the information in a properties file and use the Properties class to load it at run time. If you're using a J2EE server, database connections are configured in the server and the code references them by an abstract name.
I think I should add that if you're using a server, how to configure it and how to get the connections to your code will vary by server and J2EE level so post your environment. Using the Properties class is pretty obvious just by looking at the javadoc and the load() methods.
In glassfish, go to the admin console and under Resources create a new connection pool. That defines your database connection and will share a pool of those connections among your applications. Now under JDBC Resources, create a new entry that maps that pool to a name. The name is usually something like jdbc/myappname.
For a J2EE5 or later application, you can now add this as a class level variable:
#Resource(mappedName="jdbc/myappname") DataSource myDS;
At runtime the server will inject that resource to your database pool. Then when you need a connection, you can do this inside any method:
Connection conn = myDS.getConnection();
The result is your code doesn't have to care at all about the database connection information or managing a pool of connections. You can deploy the identical code on development and production servers, and they will get an appropriate connection. In order to get the injection, it has to be a class the server creates like an EJB, servlet, tag library handler, or JSF managed bean.

Categories

Resources