浅谈对jdbc和jtds的一些认识 博客分类: java JDBCCC++C#SQL Server
程序员文章站
2024-02-20 23:21:16
...
最近做项目用SQLSERVER2000的数据库,使用JTDS开源的驱动,跟大家谈谈个人对JDBC的一些理解。
一个DateSource可以获取多个Connection,一个Connection可以打开多个Statement,一个Statement可以打开多个ResultSet。如果我直接
conn.close();仔细翻看jtds源代码。在底层是这样实现的。
Connection------------------------close方法
看起来是如果关闭Connection,那么在此Connection上打开的所有Statement会关闭,如果关闭Statement那么在此Statement上打开的所有的
ResultSet也会关闭。如果没有特殊需要,直接关闭Connection即可。
那么在什么情况下需要先关闭ResultSet,然后关闭Statement。然后关闭Connection呢?
仔细翻看Jtds的文档。找到了以下内容:
JDBC Concurrency : CONCUR_UPDATABLE+1
SQL Server Concurrency: Pessimistic concurrency, updatable
Row Locks: Yes
Description : Row integrity isensured by locking rows
意思就是当
Statement st=Connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE+1);
ResultSet rs=st.executeQuery("SELECT * FROM TABLE2 where id=1");
rs.updateString(1,"test");
rs.updateRow() ;
该结果集就会锁定当前行,其他ResultSet不得访问。
这个时候ResultSet应当尽可能早的close()。以便释放资源。
web服务器会为每次请求创建一个线程。也就是说一次request打开一次连接即可!在一次连接上创建多个Statement。
写一个监听器,每次销毁request的时候释放数据库连接。
http://supttkl.iteye.com/admin/blogs/181419
JTDS虽然实现了数据源,但是没有实现实现连接池。所以还要借助中间件的连接池,如dbcp。。。
ConnectionJDBC2没有实现Savepoint保存点。ConnectionJDBC3实现了保存点.
那么什么时候使用保存点事务呢?
个人理解:
a向b借钱,b当时没有钱,然后到银行取出钱后委托给c,又c将钱转交给a
等c将钱转交给a的时候,发生了意外。那么钱应该在c手中,事务应该回滚到c,而不应该回滚到b。因为钱已经在c手中。
Connection conn=getConnetion();
conn.setAutoCommit(false);//启动事务
//b取钱
PreparedStatement pst=conn.prepareStatement("select * from money where bid=1");
ResultSet rs=pst.exeQuery();
int money=rs.getInt("money");
Savepoint savepoint=conn.setSavepoint("pointc");
//b将钱转交给c
PreparedStatement pst2=conn.prepareStatement("update table set money + ?");
pst2.setInt(1, money);
pst2.execute();
//c将钱转交给a的时候,出现了异常,如a不在家。
try{
PreparedStatement pstc=conn.prepareStatement("update table set money - ?");
pstc.setInt(money);
pstc.execute();
PreparedStatement psta=conn.prepareStatement("update table set money + ?");
psta.setInt(money);
psta.execute();
}catch(SQLException e){
//回滚到c
conn.rollback(savepoint)
}
一个DateSource可以获取多个Connection,一个Connection可以打开多个Statement,一个Statement可以打开多个ResultSet。如果我直接
conn.close();仔细翻看jtds源代码。在底层是这样实现的。
Connection------------------------close方法
synchronized public void close() throws SQLException { if (!closed) { try { // // Close any open statements // ArrayList tmpList; synchronized (statements) { tmpList = new ArrayList(statements); statements.clear(); } for (int i = 0; i < tmpList.size(); i++) { WeakReference wr = (WeakReference)tmpList.get(i); if (wr != null) { Statement stmt = (Statement) wr.get(); if (stmt != null) { try { stmt.close(); } catch (SQLException ex) { // Ignore } } } } try { // Tell the server the session is ending baseTds.closeConnection(); // Close network connection baseTds.close(); // Close cached TdsCore if (cachedTds != null) { cachedTds.close(); cachedTds = null; } } catch (SQLException ex) { // Ignore } socket.close(); } catch (IOException e) { // Ignore } finally { closed = true; } } } statement------------------------close方法 public void close() throws SQLException { if (!closed) { SQLException closeEx = null; try { closeAllResultSets(); } catch (SQLException ex) { if (!"HYT00".equals(ex.getSQLState()) && !"HY008".equals(ex.getSQLState())) { // Only throw exceptions not caused by cancels or timeouts closeEx = ex; } } finally { SQLException releaseEx = null; try { if (!connection.isClosed()) { connection.releaseTds(tds); } // Check for server side errors tds.getMessages().checkErrors(); } catch (SQLException ex) { // Remember any exception thrown releaseEx = ex; // Queue up any result set close exceptions if (closeEx != null) { releaseEx.setNextException(closeEx); } } finally { // Clean up everything closed = true; tds = null; connection.removeStatement(this); connection = null; // Re-throw any caught exception if (releaseEx != null) { throw releaseEx; } } } // Throw any exception caught during result set close if (closeEx != null) { throw closeEx; } } }
看起来是如果关闭Connection,那么在此Connection上打开的所有Statement会关闭,如果关闭Statement那么在此Statement上打开的所有的
ResultSet也会关闭。如果没有特殊需要,直接关闭Connection即可。
那么在什么情况下需要先关闭ResultSet,然后关闭Statement。然后关闭Connection呢?
仔细翻看Jtds的文档。找到了以下内容:
JDBC Concurrency : CONCUR_UPDATABLE+1
SQL Server Concurrency: Pessimistic concurrency, updatable
Row Locks: Yes
Description : Row integrity isensured by locking rows
意思就是当
Statement st=Connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE+1);
ResultSet rs=st.executeQuery("SELECT * FROM TABLE2 where id=1");
rs.updateString(1,"test");
rs.updateRow() ;
该结果集就会锁定当前行,其他ResultSet不得访问。
这个时候ResultSet应当尽可能早的close()。以便释放资源。
web服务器会为每次请求创建一个线程。也就是说一次request打开一次连接即可!在一次连接上创建多个Statement。
写一个监听器,每次销毁request的时候释放数据库连接。
http://supttkl.iteye.com/admin/blogs/181419
JTDS虽然实现了数据源,但是没有实现实现连接池。所以还要借助中间件的连接池,如dbcp。。。
ConnectionJDBC2没有实现Savepoint保存点。ConnectionJDBC3实现了保存点.
那么什么时候使用保存点事务呢?
个人理解:
a向b借钱,b当时没有钱,然后到银行取出钱后委托给c,又c将钱转交给a
等c将钱转交给a的时候,发生了意外。那么钱应该在c手中,事务应该回滚到c,而不应该回滚到b。因为钱已经在c手中。
Connection conn=getConnetion();
conn.setAutoCommit(false);//启动事务
//b取钱
PreparedStatement pst=conn.prepareStatement("select * from money where bid=1");
ResultSet rs=pst.exeQuery();
int money=rs.getInt("money");
Savepoint savepoint=conn.setSavepoint("pointc");
//b将钱转交给c
PreparedStatement pst2=conn.prepareStatement("update table set money + ?");
pst2.setInt(1, money);
pst2.execute();
//c将钱转交给a的时候,出现了异常,如a不在家。
try{
PreparedStatement pstc=conn.prepareStatement("update table set money - ?");
pstc.setInt(money);
pstc.execute();
PreparedStatement psta=conn.prepareStatement("update table set money + ?");
psta.setInt(money);
psta.execute();
}catch(SQLException e){
//回滚到c
conn.rollback(savepoint)
}