ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Clinton Begin <clinton.be...@gmail.com>
Subject Re: Sybase CHAINED v. UNCHAINED solution
Date Sun, 02 Jan 2005 03:42:43 GMT
I've already put this up on the wiki (feel free to attach code to the page).

Clinton


On Sat, 1 Jan 2005 12:38:27 -0700, Brandon Goodin
<brandon.goodin@gmail.com> wrote:
> actually, you could attache it to a support request in JIRA and ask
> that it be added to the "contibutor" section of the ibatis source.
> 
> On Sat, 1 Jan 2005 12:36:25 -0700, Brandon Goodin
> <brandon.goodin@gmail.com> wrote:
> > I'll start a thread on this on the developers list and see what we can
> > get setup.
> >
> > Brandon
> >
> >
> > On Tue, 28 Dec 2004 14:58:17 -0600, Severtson, Scott (Associate)
> > <Scott.Severtson@qg.com> wrote:
> > > All,
> > > Many months ago, moonpool posted a question regarding Sybase's lack of
> > > support for DDL (including temporary tables) when inside a transaction
> > > within iBATIS (http://sourceforge.net/forum/message.php?msg_id=2507161).
> > > I solved this problem for a client transitioning to iBATIS, and posted a
> > > whitepaper about the solution, pasted below. I have finally received
> > > written permission from the client to open source the code.
> > >
> > > So, where should I post the code? Anyone want to host it?
> > >
> > > For the time being, anyone in desperate need can email me at
> > > scott.severtson@qg.com.
> > >
> > > --Scott Severtson
> > >
> > > Note:
> > > As described in the white paper below, we must detect if iBATIS is using
> > > implicit or explicit transactions; three different detection methods are
> > > included for reference, supporting the DaoManager, the SqlMapClient, and
> > > one that supports both Dao/SqlMaps, but only without a JIT compilier
> > > (included because it requires no changes to *your code* to test, just
> > > changing the transaction manager; the other solutions require wrapping a
> > > proxy around the DaoManager/SqlMapClient). None of these solutions are
> > > optimal; however, they work without changing any iBATIS code, which was
> > > critical for the client. The active detector implementation can be
> > > changed by editing
> > > com.qg.open.sybase.ibatis.TransactionTypeDetector.Factory's code to hold
> > > an instance of another detector, and usage details are included in the
> > > javadocs. A much better solution would be to expose implicit/explicit
> > > transaction state at the DaoManager/SqlMapClient level.
> > >
> > > Unchained and Chained Transaction Modes
> > > -----------------------------------------
> > > Sybase supports two transaction modes: Chained and Unchained.
> > > * Unchained mode is specified by JDBC's Connection.setAutoCommit(true):
> > > insert/update/delete statements are automatically committed on execute.
> > > Sybase extends standard AutoCommit with multi-statement transaction
> > > support if BEGIN TRANSACTION is explicitly called. This mode is the
> > > default.
> > > * Chained mode is specified by JDBC's Connection.setAutoCommit(false),
> > > and conforms to the SQL 92 behavior of implicit transactions: a
> > > transaction automatically begins with the first statement, and no work
> > > is committed until COMMIT TRANSACTION is explicitly called.
> > >
> > > Unchained and Chained modes are (mostly) mutually exclusive. Unless a
> > > stored procedure is written with care to support both modes, it will
> > > generally only work in one mode.
> > >
> > > JDBC's transactional support requires Connection.setAutoCommit(false) to
> > > be set, which forces Sybase into Chained mode. However, nearly all
> > > existing stored procedures are written exclusively for Unchained mode.
> > >
> > > Temporary Tables and Transactions
> > > -----------------------------------------
> > > Sybase by default does not allow CREATE/DROP TABLE statements within
> > > transactions, including creating tables on the temporary database. While
> > > this can be enabled, Sybase strongly recommends against it: "doing so
> > > can slow performance to a halt". See http://tinyurl.com/5clrf for
> > > further information.
> > >
> > > iBATIS expects Connection.setAutoCommit(false) mode: all calls exist in
> > > an implicit, automatic transaction, and must be committed/rolled back.
> > > However, two modes are supported, implicit and explicit transactions:
> > >
> > > // ***Implicit transaction***
> > > // A Transaction object is automatically retrieved prior to calling
> > > getUser
> > > User user = userDao.getUser("fflintstone");
> > > // Transaction.commit() is automatically called after calling getUser
> > >
> > > // ***Explicit transaction***
> > > // A Transaction object is explicitly requested
> > > daoManager.startTransaction();
> > > userDao.updateUser(user);
> > > someOtherDao.updateSomethingElse(user);
> > > // Transaction.commit() is explicitly called
> > > daoManager.commitTransaction();
> > >
> > > Many existing procedures make use of temporary tables; these procedures
> > > cannot be run inside a transaction. Therefore, we must prevent iBATIS's
> > > implicit transaction support from actually beginning/committing/rolling
> > > back transactions.
> > >
> > > Solutions
> > > =======
> > > ConnectionProxy/StatementProxy/ProxyUtil
> > > -----------------------------------------
> > > JDBC's Connection.setAutoCommit(false) behavior can be simulated in
> > > Unchained mode.
> > > 1. Call BEGIN TRANSACTION prior to executing any SQL on a connection.
> > > 2. Call COMMIT/ROLLBACK TRANSACTION in place of
> > > Connection.commit/rollback()
> > > However, these manual calls would force knowledge of Sybase's
> > > limitations into the data access code, and would not work with iBATIS's
> > > transaction support.
> > > The Proxy pattern from Design Patterns by Gamma et. al. (page 207)
> > > allows us to wrap the real Connection object with our own
> > > implementation, which makes the desired BEGIN/COMMIT/ROLLBACK calls on
> > > our behalf. The proxy's setAutoCommit method enables/disables this
> > > behavior
> > >
> > > TransactionTypeDetector
> > > ------------------------
> > > Detecting implicit and explicit transactions is necessary, as implicit
> > > transactions must not actually call BEGIN TRANSACTION. The detector
> > > examines the stack trace to determine if startTransaction() was
> > > explicitly called, or if iBATIS is making the call on the user's behalf.
> > >
> > > SybaseTransaction/SybaseTransactionConfig
> > > -------------------------------------------
> > > iBATIS defines Transaction and TransactionConfig interfaces, allowing
> > > third-party developers to build in their own transactional support.
> > >
> > > public interface Transaction {
> > > public Connection getConnection() throws ...;
> > > public void commit() throws ...;
> > > public void rollback() throws ...;
> > > public void close() throws ...;
> > > }
> > > public interface TransactionConfig {
> > > public Transaction newTransaction() throws ...;
> > > // ...Other methods...
> > > }
> > > Transaction initializes connections and manages transactions, and
> > > TransactionConfig builds Transaction objects. The SybaseTransaction
> > > implementation automatically wraps a Sybase connection in a
> > > ConnectionProxy, and SybaseTransactionConfig builds SybaseTransaction
> > > instances. Additionally, SybaseTransactionConfig uses
> > > TransactionTypeDetector to specify the setAutoCommit behavior of the
> > > ConnectionProxy.
> > >
> > > Comments
> > > ========
> > > This solution adequately solves the Unchained and Chained Modes problem;
> > > any code that uses the ConnectionProxy can use setAutoCommit as JDBC
> > > specifies, while the underlying Sybase Connection remains in
> > > setAutoCommit(true)/Unchained mode. Stored procedures written for
> > > Unchained mode can be can be called from JDBC seamlessly as part of a
> > > transaction.
> > >
> > > This solution does not completely solve the Temporary Tables and
> > > Transactions problem. Stored procedures that use temporary tables must
> > > not be called in the ConnectionProxy's setAutoCommit(false) mode, such
> > > as inside an explicit iBATIS transaction. This limitation is entirely
> > > within the RDBMS, and as such, cannot be resolved by Java code.
> > >
> > > Finally, the implementation could have been simplified had
> > > ConnectionProxy's transactional support code been placed inside
> > > SybaseTransaction. However, the Connection.close() method is not handled
> > > through the Transaction interface; cleanup requires us to listen for
> > > this call. Additionally, the ConnectionProxy implementation has no
> > > dependency on iBATIS, and can be used with other persistence frameworks
> > > or straight JDBC calls.
> > >
> >
>

Mime
View raw message