diff options
Diffstat (limited to 'java/demo/Database/library/SQLRequestContext.java')
-rw-r--r-- | java/demo/Database/library/SQLRequestContext.java | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/java/demo/Database/library/SQLRequestContext.java b/java/demo/Database/library/SQLRequestContext.java new file mode 100644 index 00000000000..533e74be491 --- /dev/null +++ b/java/demo/Database/library/SQLRequestContext.java @@ -0,0 +1,181 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +// +// A SQL request context encapsulates SQL resources allocated in the +// process of executing a request, such as the database connection, +// and associated SQL statements. +// +// The request context is automatically destroyed at the end of a +// request, or if obtain is called it must be destroyed manually by +// calling destroy. +// +// When the request context is destroyed, the transaction is either +// automatically committed or rolled back, depending whether the +// request executed successfully. +// +class SQLRequestContext +{ + public static SQLRequestContext + getCurrentContext() + { + synchronized(_contextMap) + { + return _contextMap.get(Thread.currentThread()); + } + } + + public static void + initialize(Ice.Logger logger, ConnectionPool pool) + { + assert _logger == null; + assert _pool == null; + + _logger = logger; + _pool = pool; + } + + public java.sql.PreparedStatement + prepareStatement(String sql) + throws java.sql.SQLException + { + java.sql.PreparedStatement stmt = _conn.prepareStatement(sql); + _statements.add(stmt); + return stmt; + } + + public java.sql.PreparedStatement + prepareStatement(String sql, int autoGeneratedKeys) + throws java.sql.SQLException + { + java.sql.PreparedStatement stmt = _conn.prepareStatement(sql, autoGeneratedKeys); + _statements.add(stmt); + return stmt; + } + + // Called to obtain ownership of the context. The context is no + // longer destroyed automatically when the current request has + // completed. + public void + obtain() + { + if(_trace) + { + _logger.trace("SQLRequestContext", "obtain context: " + this + + " thread: " + Thread.currentThread()); + } + _obtain = true; + } + + public void + destroy(boolean commit) + { + // Must only be called on an obtained context. + assert _obtain; + destroyInternal(commit); + } + + public void + error(String prefix, Exception ex) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + _logger.error(prefix + ": error:\n" + sw.toString()); + } + + SQLRequestContext() + { + _conn = _pool.acquire(); + + synchronized(_contextMap) + { + if(_trace) + { + _logger.trace("SQLRequestContext", "create new context: " + this + + " thread: " + Thread.currentThread() + + ": connection: " + _conn); + } + + _contextMap.put(Thread.currentThread(), this); + } + } + + // Called only during the dispatch process. + void + destroyFromDispatch(boolean commit) + { + synchronized(_contextMap) + { + // Remove the current context from the thread->context + // map. + SQLRequestContext context = _contextMap.remove(Thread.currentThread()); + assert context != null; + } + + // If the context was obtained then don't destroy. + if(!_obtain) + { + destroyInternal(commit); + } + } + + private void + destroyInternal(boolean commit) + { + // Release all resources. + try + { + if(commit) + { + _conn.commit(); + if(_trace) + { + _logger.trace("SQLRequestContext", "commit context: " + this); + } + } + else + { + _conn.rollback(); + if(_trace) + { + _logger.trace("SQLRequestContext", "rollback context: " + this); + } + } + + java.util.Iterator<java.sql.Statement> p = _statements.iterator(); + while(p.hasNext()) + { + p.next().close(); + } + } + catch(java.sql.SQLException e) + { + error("SQLRequestContext", e); + } + + _pool.release(_conn); + + _statements.clear(); + _conn = null; + } + + // A map of threads to request contexts. + private static java.util.Map<Thread, SQLRequestContext> _contextMap = + new java.util.HashMap<Thread, SQLRequestContext>(); + + private static Ice.Logger _logger = null; + private static ConnectionPool _pool = null; + + private boolean _trace = true; + private java.util.List<java.sql.Statement> _statements = new java.util.LinkedList<java.sql.Statement>(); + private java.sql.Connection _conn; + private boolean _obtain = false; +} |