database connection on local machine - database

I was originally coding on a server with Apache installed and used this function to connect to the database
public Connection getDBConnection()
{
java.sql.Connection conn=null;
//synchrnized(this)
try
{
DriverManager.registerDriver(new OracleDriver());
conn = DriverManager.getConnection("jdbc:oracle:thin:#dukeorrac01:1521:ORDB1","nrsc","nrsc");
}
catch (Exception e)
{
e.printStackTrace();
}
return conn;
}
Probably not the best way to do it, but it worked. However, I've moved to coding on my local machine and I was given jboss as an IDE to work with. I've gotten everything working (sorta) except, it seems to be connecting to a different databse. I get exhausted resultsets (which isn't right). I "thought" the "getConnection("jdbc:oracle....") was what established the connection to the actual database.
Why is this not working on my local machine when it worked perfectly fine on the remote server?
P.S. I'm new to database/server configuration stuff. So, don't assume I know some step in setting up a database or server. Also, I did not create this orginally. It was given to me to use.
Thanks

The error seems to indicate that you are not closing your result sets properly. In the following example see how after a statement is executed you have to close those resources in the finally block.
W.r.t why you did not see this error before is probably because your server probably had lots of resources whereas your local machine has limited resources and your default settings are not modified to reflect the needs of your application.
In general, its better to do basic house keeping like closing all the open result sets and statements whether or not you have enough resources allocated on your DB.
public void getDBConnection() {
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
connection = DriverManager.getConnection("jdbc:oracle:thin:#dukeorrac01:1521:ORDB1","nrsc","nrsc");
statment = connection.createStatement();
statement.setFetchSize(Integer.MIN_VALUE);
// Do more stuff, iterate to ResultSet etc...
} catch (SQLException ex) {
// Exception handling stuff
...
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) { /* ignored */}
}
if (statment != null) {
try {
statment.close();
} catch (SQLException e) { /* ignored */}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) { /* ignored */}
}
}
}

Related

Can database Snapshots be passed to other methods?

I have tried to write this code in three different ways but none of them work correctly.
I did not want to write any business logic code in the class that opens and closes the database, so I have a database class. I am trying to take a Snapshot of the database to send it to the business logic class.
However what is the correct way to send a Snapshot or Iterator across to another class?
Here is my current code in the database connection class trying to return an Iterator to the business logic class:
public synchronized DBIterator getSnapShot() throws IOException {
ReadOptions ro = new ReadOptions();
Options options = new Options();
DBIterator iterator = null;
try {
DB database = (factory.open(new File("myFilePath"), options));
ro.snapshot(database.getSnapshot());
iterator = database.iterator(ro);
return iterator;
} catch (Exception e) {
e.printStackTrace();
} finally {
getLinkPacDatabase().close();
}
return iterator;
}
Then I try to iterate in the business logic class like this:
for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
I have also tried to grab a Snapshot only from the database like this, but it also does not work because the database connection has to close obviously:
public synchronized Snapshot generateSnapshot() {
Snapshot snapshot = null;
DB database = null;
try {
database = factory.open(new File("myFilePath"), options);
snapshot = database.getSnapshot();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
database.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return snapshot;
}
There is no documentation for the levelDb Java port library I am using, therefore I am hoping someone can explain if I am using Snapshots incorrectly.

How to send logs to GrayLog from T-SQL procedures?

I can send logs to log collectors from C# applications using log4net+GELF appender.
But how to send logs to GrayLog from T-SQL procedures?
There are code:
WinForms app works fine, I run it on the same machine where SQL Server installed. I see all logs received in GrayLog:
private void button1_Click(object sender, EventArgs e)
{
string facility = "DoBeDo";
string host = "my-host-name";
int port = 12201;
try
{
using (var logger = new GrayLogUdpClient(facility, host, port))
{
logger.Send("Hello", "Jonny Holiday", new { Username = "John", Email = "jonny#example.com" });
}
}
catch(Exception xx)
{
Console.WriteLine("***Exception:{0}", xx.Message);
}
}
There is SQLCLR code, it works, I see messages in SSMS but no any records in GrayLog and no any exceptions:
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void SqlSPHelper(SqlString msg)
{
try
{
SqlContext.Pipe.Send(#"SqlSPHelper:: Start");
string facility = "DoBeDo";
string host = "my-host-name";
int port = 12201;
try
{
using (var logger = new GrayLogUdpClient(facility, host, port))
{
logger.Send("Hey", "Donny Hooligan", new { Username = "Donald", Email = "Donny#example.com" });
}
}
catch (Exception xx)
{
Console.WriteLine("***Exception:{0}", xx.Message);
}
}
catch(Exception xx)
{
SqlContext.Pipe.Send("1:"+xx.Message);
}
SqlContext.Pipe.Send(#"SqlSPHelper:: Completed");
}
What is wrong? How to send logs to GrayLog?
I think you can do this in couple of ways:
Define a CLR stored procedure, which does the logging part
In the CATCH Block of the stored procedure, RAISERROR WITH LOG to write to Windows event viewer & SQL Server error log. Later you can filter and read these events from event viewer in your GrayLog.
The first method is better, as it is cleaner. Second method makes the SQL Server error log to have many log entries, which would cause false alarms for DBA team.

Deploy an app in Payara using existing database in MSSQL

I am totally new to Payara and I have question about how can I deploy an app which uses existing database? So I have .war file and .bak file (MSSQL backup).
Thanks a lot.
In my opinion you're a little bit confused about Payara capabilities. Payara is an Application Server based on Glassfish, it doesn't matter the kind of database that any of your deployed applications has to access and of course the database should exists.
For MSSQL database you could use Microsoft JDBC driver. There's an excellent tutorial here:
On the other hand, it possible to configure a database connection pool in Payara/Glassfish server.
In the official Payara's blog there are interesting posts and one focused on database connection pool that can be found here .
Don't worry if the article is talking about a derby database, you only has to modify Microsoft JDBC params properly when configurating the pool.
In addition, if you decide to use connection pool it's necessary to made some changes inside your application:
Change method getConnection() from DRIVER_MANAGER (jdbc) to DATASOURCE
DRIVER_MANAGER:
public Connection getConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
Properties properties = new Properties();
properties.setProperty("user", DB_USER);
properties.setProperty("password", DB_PWD);
properties.setProperty("useSSL", "false");
properties.setProperty("autoReconnect", "true");
if (connection == null || connection.isClosed()) {
connection = DriverManager
.getConnection("jdbc:mysql://"+DB_HOST+":"+DB_PORT+"/" + SCHEMA.substring(0, SCHEMA.length() - 1), properties);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
DATA_SOURCE:
public Connection getConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
Properties properties = new Properties();
properties.setProperty("user", DB_USER);
properties.setProperty("password", DB_PWD);
properties.setProperty("useSSL", "false");
properties.setProperty("autoReconnect", "true");
InitialContext ctx;
ctx = new InitialContext();
ds = (DataSource) ctx.lookup("database_resource_pool");
if (connection == null || connection.isClosed()) {
connection = ds.getConnection();
}
} catch (NamingException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
Add resource-ref to web.xml
<resource-ref>
<res-ref-name>database_db_pool</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Add resource-ref to WebContent/WEB-INF/glassfish-web.xml
<resource-ref>
<res-ref-name>database_db_pool</res-ref-name>
<jndi-name>database_db_pool</jndi-name>
</resource-ref>

ZombieCheck Exception - This SqlTransaction has completed; it is no longer usable -- during simple commit

I have the following code which performs a commit of a single row to a database table (SQL 2008 / .NET 4)
using (var db = new MyDbDataContext(_dbConnectionString))
{
Action action = new Action();
db.Actions.InsertOnSubmit(dbAction);
db.SubmitChanges();
}
Normally everything is fine, but once in a while I get the following exception:
System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable.
at System.Data.SqlClient.SqlTransaction.ZombieCheck()
at System.Data.SqlClient.SqlTransaction.Rollback()
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
There are a number of similar questions on SO but I after reading them I cannot work out the cause.
Could this be simply due to a SQL timeout (the exception occurs close to 25s after the call is made)? Or should I expect a SQL timeout exception in that case?
Does anyone know what else may cause this?
The DataContext.SubmitChanges method has the following code lines in it's body:
// ...
try
{
if (this.provider.Connection.State == ConnectionState.Open)
{
this.provider.ClearConnection();
}
if (this.provider.Connection.State == ConnectionState.Closed)
{
this.provider.Connection.Open();
flag = true;
}
dbTransaction = this.provider.Connection.BeginTransaction(IsolationLevel.ReadCommitted);
this.provider.Transaction = dbTransaction;
new ChangeProcessor(this.services, this).SubmitChanges(failureMode);
this.AcceptChanges();
this.provider.ClearConnection();
dbTransaction.Commit();
}
catch
{
if (dbTransaction != null)
{
dbTransaction.Rollback();
}
throw;
}
// ...
When the connection times out, the catch block is executed and the dbTransaction.Rollback(); line will throw a InvalidOperationException.
If you had control over the code, you could catch the exception like this:
catch
{
// Attempt to roll back the transaction.
try
{
if (dbTransaction != null)
{
dbTransaction.Rollback();
}
}
catch (Exception ex2)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
throw;
}
YES! I had the same issue. The scary answer is that SQLServer sometimes rolls back a transaction on the server side when it encounters an error, and does not pass the error back to the client. YIKES!
Look on the Google Group microsoft.public.dotnet.framework.adonet for "SqlTransaction.ZombieCheck error" Colberd Zhou [MSFT] explains it very well.
and see aef123's comment on this SO post
May I suggest that connection closes earlier that transaction commits. Then the transaction is rolled back. Check this article on MSDN Blog.

java:not able to set auto commit mode with value false in java 1.4 api?

sql server 200
java 1.4
jboss 3
HI am getting exception message
"You cannot set autocommit during a managed transaction"
code is below
try {
try {
connection = getConnection();
} catch (Exception e) {
throw new ConnectionException(e.getMessage());
}
for(int i=0;i<recordIds.size();i++)
{
String currentRecordId=(String)recordIds.get(i);
try
{
//exception on this line connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement(getSQL("PurgeRecordInDumpData"));
preparedStatement.setLong(1,Long.parseLong(currentRecordId));
int numberOfUpdates=preparedStatement.executeUpdate();
if(numberOfUpdates!=1)
{
throw new Exception("Record with record id "+currentRecordId +"could not be purged.");
}
preparedStatement.close();
connection.commit();
listOfPurgedRecords.add(currentRecordId);
}
catch(Exception e)
{
connection.rollback();
}
}
return listOfPurgedRecords;
}
what is cause of this exception and what does it mean?
The error is clear, you cannot set autocommit while you are in a managed transaction. You should not even need to set this to false as that is the default, you use to enable it autocommit.
I am not sure if you are using J2EE and EJB's, if you are and you want to ENABLE autocommit, you can change your setting to bean managed transaction (BMT) and this would allow you to modify this setting.
However, the way you are using it in your code you don't need to set it to false, everything is done in transactions and you control them with commit or rollback.

Resources