Nhibernate中session的状态与session.connection.state状态的差别的解释
在項目中用到了nhibernate,但是需要判斷數據連接的狀態,在NHIbernate的文檔中找了半天,英文的中文的都看了一遍,都沒找到相關的說明 。后來在Hibernate的論壇上才找到了一些說明。摘錄如下:
?Post subject: Check if database is available
Posted: Tue Sep 18, 2007 10:33 am?
?
?
?
Beginner
?
?
Joined: Tue May 30, 2006 10:55 am
Posts: 21
?
Is there a best practice for testing a database connection? Because I am using more than one database I hope there is such a functionality inside of NHibernate.
?
Hibernate version: 1.2.0
Name and version of the database you are using: MS SQL, Informix
?
?
?
?
?
Top
??
?
?
?
?
?
jlockwood
?
?
?Post subject:
Posted: Tue Sep 18, 2007 10:46 am?
?
?
?
Regular
?
?
Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
?
To support multiple databases you would need a config file (or programattically, config methods) for each database concerned. You would also need to create a session factory for each database.
?
As far as testing for each connection, you could wrap the configuration of each session factory in a try/catch. You would catch the config error raised if the database isn't found (I'm not sure what it is off hand) and then could dump the exception and log the error using log4net (only if the failed connection is not a terminal condition).
?
I'm not sure what it would mean to you if you couldn't connect to one of the two databases, so I can't say what the behavior should be if a connection failed. In any case, you could have a central SessionManager that can hand out sessions from both factories. This could be a thread-safe singleton. I haven't tested shared transaction contexts across 2 databases, but I imagine that there's some support for enlisting transactions from sessions on the other database (I'm only guessing).
?
Billy McCafferty has a decent example of using multiple databases with NHibernate here:
?http://www.codeproject.com/aspnet/NHibe ... ctices.asp
I wrote a short blog a while bag that shows how to enlist transactions into an ADO Command, but that was for doing work outside the cache but within the same transaction context:
?http://www.lostechies.com/blogs/joshua_ ... ction.aspx
Does that help?
_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...
?
?
?
?
Top
??
?
?
?
?
?
torrud
?
?
?Post subject:
Posted: Tue Sep 18, 2007 11:10 am?
?
?
?
Beginner
?
?
Joined: Tue May 30, 2006 10:55 am
Posts: 21
?
Thanks for your reply. I will read the articles soon.
But at the moment I am standing a few steps earlier. All I want to do with the databases works for the moment but I get in trouble when a database is not accessible maybe during a network error or a mistyped password etc.
?
So I have to check whether a connection to a database is possible. At the moment I catch the exceptions from the session factory but I hoped that there is a better way without throwing/catching exceptions to test the configuration. I can not give the exception message to the user because it is to much technical. And so I get in trouble how to determine what goes wrong.
?
Is there no smarter way?
?
?
?
?
?
Top
??
?
?
?
?
?
jlockwood
?
?
?Post subject:
Posted: Tue Sep 18, 2007 11:44 am?
?
?
?
Regular
?
?
Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
?
For helping in debugging, you could use log4net to intercept NHibernate logs. That would help with trouble shooting.
?
For instance, if you had a malformed password you would get an ADOException forces by the database itself. Unfortunately, thet won't log in you NHibernate logs all you'll see is something like this:
?NHibernate.Connection.DriverConnectionProvider [(null)] - Obtaining IDbConnection from Driver
?
...and then the log stops.
I'm using Oracle, so even if the database can't be found I'll still get an Oracle exception back as an ADOException (TNS not resolved). From NHibernate's perspective it will look the same:
?DEBUG NHibernate.Connection.DriverConnectionProvider [(null)] - Obtaining IDbConnection from Driver
?
For failed connections and authentication you won't see an exception until you try to begin a new transaction or flush a transient object to the database. That being said, you could force a check of the connection with something like this:
?
Code:
session.Connection.Open();
?
If the database can't be found or authentication is bad and ADOException would be raised when forcing the Open().
?
So, beging transaction or a forced open would raise the exception and allow you to do a check before continuing execution.
?
Does that do it for you?
_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...
?
?
?
?
Top
??
?
?
?
?
?
torrud
?
?
?Post subject:
Posted: Wed Sep 19, 2007 8:45 am?
?
?
?
Beginner
?
?
Joined: Tue May 30, 2006 10:55 am
Posts: 21
?
I am followed your advice and wrote this code:
Code:
internal bool IsDatabaseAvailable
{
? get
??? {
????? bool available = false;
????? ISession session = null;
????? try
????? {
??????? session = factory.OpenSession(); //gets a new session from the session factory
??????? available = session.IsConnected;
????? }
????? catch(Exception ex)
????? {
??????? //add entry to application log???
????? }
????? finally
????? {
??????? if (null != session)
????????? session.Close();
????? }
????? return available;
? }
}
?
But I get now one problem. If I use a wrong username session.IsConnected returns true but the session.Connection property returns an ADOException as it should. Why the IsConnected property returns "true" and not "false"? Maybe a bug?
?
Any suggestions?
?
?
?
?
Top
??
?
?
?
?
?
jlockwood
?
?
?Post subject:
Posted: Wed Sep 19, 2007 10:38 am?
?
?
?
Regular
?
?
Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
?
?
torrud wrote:
But I get now one problem. If I use a wrong username session.IsConnected returns true but the session.Connection property returns an ADOException as it should. Why the IsConnected property returns "true" and not "false"? Maybe a bug?
Any suggestions?
?
session.IsConnected is different. You can think of it as IsConnectable, since you can have "Connected" and "Disconnected" sessions. If you call session.Diconnect(), you can no longer persist data to the database. session.Reconnect() will allow you to persist to the DB again. This does not mean that you have an open connection, it just means that you are capable of opening a connection if you were to begin a transaction. If you look at the NHibernate log file, I believe that you wouldn't see the line that says that the connection was opened. This is because the connection isn't needed yet.
?
Calling session.Connection.Open() would force the connection to open and thus raise your exception.
?
Make sense?
_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...
?
?
?
?
Top
??
?
?
?
?
?
torrud
?
?
?Post subject:
Posted: Wed Sep 19, 2007 12:13 pm?
?
?
?
Beginner
?
?
Joined: Tue May 30, 2006 10:55 am
Posts: 21
?
?
jlockwood wrote:
session.IsConnected is different. You can think of it as IsConnectable, since you can have "Connected" and "Disconnected" sessions. If you call session.Diconnect(), you can no longer persist data to the database. session.Reconnect() will allow you to persist to the DB again. This does not mean that you have an open connection, it just means that you are capable of opening a connection if you were to begin a transaction. If you look at the NHibernate log file, I believe that you wouldn't see the line that says that the connection was opened. This is because the connection isn't needed yet.
Calling session.Connection.Open() would force the connection to open and thus raise your exception.
Make sense?
?
Yes, it does. But one additional question. There is a property called session.IsOpen. This property is still "true" like session.IsConnected but can I have a disconnected session which is open? I thought one of these both properties should give me the right information but they do not. For the moment I have changed my code and now it works.
?
Code:
.
.
.
try
{
? session = factory.OpenSession();
?
? //if something is wrong the following statement throws an ADOException
? available = (ConnectionState.Open == session.Connection.State);
}
.
.
.
?
?
?
?
?
Top
??
?
?
?
?
?
jlockwood
?
?
?Post subject:
Posted: Wed Sep 19, 2007 1:44 pm?
?
?
?
Regular
?
?
Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
?
Yes...
If you have an open session and call:
Code:
session.Disconnect();
session.IsOpen would equal true
session.IsConnected would equal false
If you have an open session and call:
Code:
session.Close();
?
session.IsOpen would equal false
session.IsConnected would equal false
If you try to save using a disconnected session, you get a HibernateException.
I think you might be able to load objects from a disconnected session's cache using session.Load(entityId, typeof(EntityType)), but I haven't tested this so I don't know for certain.
?
In a nutshell,
session.IsOpen indicates if session is open regardless of connection state
session.IsConnected indicates if a session is "Connected" and thus can establish new AdoConnections
_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...
?
?
?
?
Top
??
?
?
?
?
?
?
Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending?
?
?原來,還是要以session.connection.state為準來判斷連接的狀態。
?
?
?
?
總結
以上是生活随笔為你收集整理的Nhibernate中session的状态与session.connection.state状态的差别的解释的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 又不能起床python好学吗
- 下一篇: “扎金花FANS”进行了改进