VB.net: Any problems using a Shared method for getting a db connection? - vb.net

I have a utility class that creates & returns a db connection:
Public Shared Function GetConnection() as OracleConnection
dim c as New OracleConnection()
... set connection string...
c.Open()
Return c
End Function
Is there any risk of concurrent calls returning the same connection? The connection string enables pooling.

Since you are returning a new connection each time you will not have any concurrency issues. If you were using a Shared method to return multiple references to the same instance, that could be a problem but that is not what you are doing here.
You are safe to use this method in this way as long as you are always returning a new instance of your database connection object each time. Any connection pooling will also work the same as it always would - you won't need to worry about your Shared method usage created problems there either.

Forget the concurrent calls issue for a moment. If there is any connection pooling going on you will absolutely have reuse of the same underlying database connections, even if they don't use the same object.
This is generally a desirable thing as opening a connection to the DB can be an expensive operation.
Are you worried about closing the connection object out from under another caller? If so, as another response pointed out, I think you are safe with the code you provided.

I don't think so.
Since c is a local variable ("stack variable") and not a static one every call has it's own instance of c.
Next you create a new object (the connection) and return this.

Shouldn't be any problem with concurrency, because each call is a new connection.
I might make one change, though: make the method private.
This will force you to put all your data access code in one class and push to create a nice, separate data access layer. At very least make it internal so that your data access layer is confined to a single assembly (that's separate from the rest of your code).

Related

Keeping SAP's RFC data for consecutive calls of RFC using JCO

I was wondering if it was possible to keep an RFC called via JCO opened in SAP memory so I can cache stuff, this is the scenario I have in mind:
Suppose a simple function increments a number. The function starts with 0, so the first time I call it with import parameter 1 it should return 1.
The second time I call it, it should return 2 and so on.
Is this possible with JCO?
If I have the function object and make two successive calls it always return 1.
Can I do what I'm depicting?
Designing an application around the stability of a certain connection is almost never a good idea (unless you're building a stability monitoring software). Build your software so that it just works, no matter how often the connection is closed and re-opened and no matter how often the session is initialized and destroyed on the server side. You may want to persist some state using the database, or you may need to (or want to) use the shared memory mechanisms provided by the system. All of this is inconsequential for the RFC handling itself.
Note, however, that you may need to ensure that a sequence of calls happen in a single context or "business transaction". See this question and my answer for an example. These contexts are short-lived and allow for what you probably intended to get in the first place - just be aware that you should not design your application so that it has to keep these contexts alive for minutes or hours.
The answer is yes. In order to make it work, you need to implement two tasks:
The ABAP code needs to store its variable in the ABAP session memory. A variable in the function group's global section will do that. Or alternatively you could use the standard ABAP technique "EXPORT TO MEMORY/IMPORT FROM MEMORY".
JCo needs to keep the user session between calls. By default, JCo resets the backend-side user session after every call, which of course destroys all data stored in that user session memory. In order to prevent it, you need to use JCoContext.begin() and JCoContext.end() to get a stateful RFC connection that keeps the user session alive on backend side.
Sample code:
JCoDestination dest = ...
JCoFunction func = ...
try{
JCoContext.begin(dest);
func.execute(dest); // Will return "1"
func.execute(dest); // Will return "2"
}
catch (JCoException e){
// Handle network problems, ABAP exceptions, SYSTEM_FAILUREs
}
finally{
// Make sure to release the stateful connection, otherwise you have
// a resource-leak in your program and on backend side!
JCoContext.end(dest);
}

Passing an ADO SQL connection ByVal

I have an existing application written in Visual Basic. It's a web application build on ASP.NET and WCF that we use for reporting.
The result is a page that refreshes it's data every set amount of time. Usually after a day or so, this particular page crashes and the service must be reset, however other pages work. My working theory has to do with connections.
Connections to SQL Server are made through the class SQLDataAccess. This class creates a new connection when it is instantiated, the connection can be closed by calling a method on the class.
Most calls look like this:
Try
existingConnection.DataRequest.CommandText = "dbo.p_Select_Table"
DataAccessConnection.ExecuteDataSet()
Catch
Finally
If(existingConnection IsNot Nothign) Then
existingConnection.closeConnection()
End If
End Try
However two connections are initially made, then both connections are passed around more than this bug report was. They get passed ByVal.
Will this create new connections and neglect to close the old one?
When you pass any reference type by value, what you are passing is a reference. No object is copied. Passing a method parameter by value is basically just the same as assigning one variable to another. If the type is a value type then the object is copied and both variables contain different objects. For reference types, both variables refer to the same object. It's just like objects in the real world. If I lend you my car, does that mean there are two cars? No it doesn't, and it's the same when you pass a reference type object by value.

Question regarding org.apache.commons.dbcp.BasicDataSource

I fixed some bug related to the way we were using BasicDataSource and though I understand part of it I still have some questions unanswered :)
Problem:
The application was not able to auto-connect to the database after a db failure.
Application is using org.apache.commons.dbcp.BasicDataSource class as a TCP-connection pool for a JDBC connection to Oracle db.
Fix:
After some research I discovered that in BasicDataSource testOnBorrow and testOnreturn were not set. I provided the validation query to test connections. This fixed the problem
Max no of connections in pool was set to 1
My Understanding:
The connection pool would hand over a connection to the application.
What I think was happening was the application MAGICALLY returned the bad collection to the pool when it db crashed . Now since the Pool does not know if it is a bad connection it would hand over the same connection to the application next time it needs it causing the application to not auto-reconnect to db.
Now, after the fix.. whenever a bad connection is returned to the connection pool it would be discarded and wont be used again because of the fix I made above.
Now I know that BasicDataSource wraps the connection before giving to the application, such that whenever application says con.close ..BasicDataSource would know that the connection is not used any more.. it will take care of either returning the connection to the pool or discardigg etc.
Unanswered Question:
However what I do not understand is what makes the application MAGICALLY return the connection to the connection pool when its broken[Note that con.close method is not called when the connection exits un-gracefully]. There is no way of BasicDataSource to know that the connection closed or there is ?. Can someone point me to code for that ?
I my overall understanding connect of why the fix worked ??
Now, I know that this is kind of an old thread, but it's high on google search results, so I thought I might give it a quick answer. For more information on configuring the BasicDataSource, you should reference the DBCP Configuration page: http://commons.apache.org/proper/commons-dbcp/configuration.html
To answer the "unanaswered" question of "How does BasicDataSource know when a connection is abondoned and needs to be returned to the connection pool?" (paraphrased)...
org.apache.commons.dbcp.BasicDataSource is able to monitor traffic and usage on the connections it offers by using a wrapper class for the Connection. Every time you call a method on the connection or any Statements created from the connection, you are actually calling a wrapper class that implements an interface or extends a base class with those same methods (Hurray for Polymorphism!). These custom methods allow the DataSource to know whether or not a Connection is active.
On the BasicDataSource itself, there is a property called "removeAbandoned" and another called "removeAbandonedTimeout" that are used to configure this behavior of returning abondonded connections to the connection pool.
"removeAbandoned" is a boolean that indicates whether abandoned connections should be returned to the pool. Defaults to "false".
"removeAbandonedTimeout" is an int, that represents the number of seconds of inactivity that should be allowed to pass before a connection is considered to be abandoned. Default value is 300 (about 5 minutes).
Looking at the test for abandoned connections, it appears that when all connections in the pool are "in use" when a new connection is requested, the "in-use" connections are tested for abandonment (they maintain a timestamp of last used time).
See BasicDataSource#setRemoveAbandoned(boolean) and BasicDataSource#setRemoveAbandonedTimeout(int)
Regardless of how clever or not your connection pool is in closing abandoned connections, you should always ensure each connection is closed in a finally block, e.g.:
Connection conn = getConnection();
try {
... // perform work
} finally {
conn.close();
}
Or use some other means such as Apache DBUtils.

Sharing Non-Persistent Objects Between Contexts in Core Data?

I was wondering if there is a way to share an NSManagedObject between two or more NSManagedObjectContext objects running in the same thread.
I have the following problem: I have one main context shared through all my code in the application and several different contexts that are created for each remote fetch request that I issue. (I created a custom class that fetches remotely and inserts all the objects found in the server in his own NSManagedObjectContext). Those fetch requests may run simultaneously since they use NSURLConnection objects that may end at different times. If the same remote object gets fetched by different connections, I will end up with duplicates at the moment of saving and merging the context with the main one. (That is, objects that have the same remote ID but a different objectID).
One possible solution would be to save (and so persist) every object as soon as it is created but I can't do that because it may have some relationships that may still have not been filled and won't validate during the save operation.
I'm really looking forward to a method that allows you to share the same non-persistent instance of an object between context. If anybody has encountered this issue and came up with a solution, I would be pleased to know!
Context cannot communicate between each other save through their stores. However, you can insert a managed object with a nil managed object context and it will be independent (albeit without relationships) of any context. You could pass that independent managed object around however you wished and insert it into a context when you needed to persist it. This is dangerous but possible.
However, if you're not running each connection on a separate thread then you don't gain anything by having multiple context. Each connection object will activate its delegate in sequence on the main thread. In this case, your easiest solution would be to use the same delegate for all the connections and let the delegate handle the insertions into a single context. To prevent duplication, just do a fetch on the remoteID and see if you get back an extant object before inserting a new object for that remoteID.
I don't think what you want to do is possible. I mean if you want to share changes between different contexts, you got to use notifications and merge it whenever did save or did change occur. But in your case, I'd say just use 1 context and save in the end. Or a less elegant way: save all the remote ids temporary in your app and check before inserting new ones. In this case, you can continue use multiple contexts and save after each didfinishloading.

SaveOrUpdate Vs Update and Save in NHibernate

What is the difference between SaveOrUpdate and Save/Update in NHibernate. Why wouldnt you just always use SaveOrUpdate? Also, what is the point of SaveOrUpdateCopy?
Chapter 9 covers all of this better than I can:
http://nhibernate.info/doc/nh/en/index.html
But cliff notes:
Save() takes a new object without an identifier and attaches it to the session. The object will be INSERT'd.
Update() takes an existing object that has an identifier but is not in the session and attaches it to the session. The object will be UPDATE'd.
SaveOrUpdate() looks at the identifier and decides what is necessary in the above.
SaveOrUpdateCopy() is special in that say you have two objects with the same identifier -- one in the session and one not. If you try and update the one not in the session an exception is thrown normally (you are now trying to attach two objects that represent the same persistent object to the session). SaveOrUpdateCopy() copies the non-session object state to the session object state.
I'm not sure how you are going to use NH, but for a lot of cases all you need is Save(). The session is doing ALL of the work necessary to know what has to be updated and simply Flush() or a Commit() does everything you need.