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 <[EMAIL PROTECTED]> 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) > <[EMAIL PROTECTED]> 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 > > [EMAIL PROTECTED] > > > > --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. > > >

