Many thanks for the reply, Clinton - but sadly this doesn't seem to fix the problem. My understanding was that readonly need only be set to "false" if a thread is likely to change the contents of the returned object - this is not the case in my example application (indeed, the returned object is a String).
I've appended my code and iBATIS configuration files below - I'd appreciate it if you could tell me if I'm doing anything obviously wrong. My understanding was that a SqlMapClient object could safely be used from multiple threads (and that it would handle the caching appropriately). Thanks, Alistair. IBatisTest.java: ------------------------------------------------------------ package test; public class IBatisTest implements Runnable { private SqlMapClient sql; public IBatisTest() throws Exception { // create the SQL map Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml"); this.sql = SqlMapClientBuilder.buildSqlMapClient(reader); } public void runTest() throws Exception { this.sql.startTransaction(); String value = (String)this.sql.queryForObject("db.getValue"); System.out.println("Value is " + value); // "1" this.sql.update("db.updateValue", "2"); value = (String)this.sql.queryForObject("db.getValue"); System.out.println("Value is " + value); // "2" // start the other thread new Thread(this).start(); // wait for a bit Thread.sleep(2000); // roll back the transaction this.sql.endTransaction(); value = (String)this.sql.queryForObject("db.getValue"); System.out.println("Value is " + value); // "2" (expecting "1") } // second thread public void run() { try { String value = (String)this.sql.queryForObject("db.getValue"); System.out.println(" Value is " + value); // "2" (expecting "1") } catch (Exception x) { throw new RuntimeException(x); } } public static void main(String[] args) throws Exception { new IBatisTest().runTest(); } } ------------------------------------------------------------ SqlMapConfig.xml: ------------------------------------------------------------ <?xml version="1.0" encoding="windows-1252" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "sql-map-config-2.dtd"> <sqlMapConfig> <settings useStatementNamespaces="true" lazyLoadingEnabled="true" enhancementEnabled="true" statementCachingEnabled="false" /> <transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="oracle.jdbc.OracleDriver"/> <property name="JDBC.ConnectionURL" value="..."/> <property name="JDBC.Username" value="..."/> <property name="JDBC.Password" value="..."/> </dataSource> </transactionManager> <!-- at least one SQL Map is required for this to be a valid configuration file --> <sqlMap resource="SqlMap.xml"/> </sqlMapConfig> ------------------------------------------------------------ and SqlMap.xml: ------------------------------------------------------------ <?xml version="1.0" encoding="windows-1252" ?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "sql-map-2.dtd"> <sqlMap namespace="db"> <cacheModel id="cache" type="FIFO" readOnly="false" serialize="true"> <flushOnExecute statement="db.updateValue"/> <property name="size" value="10"/> </cacheModel> <insert id="updateValue" parameterClass="String"> update VALUES set VALUE=#value# where ID=1 </insert> <select id="getValue" resultClass="String" cacheModel="cache"> select VALUE from VALUES where ID=1 </select> </sqlMap> ------------------------------------------------------------ -----Original Message----- From: Clinton Begin [mailto:clinton.be...@gmail.com] Sent: 12 January 2009 15:23 To: user-java@ibatis.apache.org Subject: Re: iBATIS caching / transaction isolation question The uncommitted data would be seen by thread B as you expect, *if* the cache is configured as read-only. To stop this problem, set the cache to read/write and serializable. Sorry for the confusing configuration here. Clinton On 1/12/09, Young, Alistair <alistair.yo...@logica.com> wrote: > Apologies for following up my own post... > > I carried out a simple test and found that transaction isolation is > not maintained. Also, the cache is not flushed in the event of a > transaction being rolled back. > > The sequence of events was: > > Thread A: start transaction > Thread A: select value ("1" is returned) Thread A: update value to "2" > Thread A: select value ("2" is returned) > > Thread B: select value ("2" is returned - not "1") > > Thread A: rollback transaction > Thread A: select value ("2" is returned - not "1") > > Is this the expected behaviour? > > If not, what might I be doing wrong? If so, how do people deal with > this behaviour? > > Thanks for any advice, > > > Alistair. > > ________________________________ > > From: Young, Alistair > Sent: 12 January 2009 10:54 > To: user-java@ibatis.apache.org > Subject: iBATIS caching / transaction isolation question > > > Hello all, > > I wonder if somebody could clarify for me how iBATIS caching works > with regards to transaction isolation. > > Suppose I have a cache set up with is used when a "selectAllItems" > statement is invoked, and flushed when an "updateItem" statement is > invoked. > > Suppose then that thread A starts a transaction, invokes updateItem > and then selectAllItems. Then, before thread A completes the > transaction, thread B invokes selectAllItems. > > Is transaction isolation maintained, or does thread B end up seeing > the > (uncommitted) data that thread A has updated? > > I should add that I haven't actually tried this yet - but I'd like to > know what the expected behaviour is before getting stuck in. > > In our particular use case, we're making use of a custom > TransactionConfig (which is essentially the same as "EXTERNAL" but > handles connection creation slightly differently). And we're not > making any explicit calls to the iBATIS transaction methods. > > Many thanks! > > > Alistair. > > > > > Please help Logica to respect the environment by not printing this > email / Merci d'aider Logica à préserver l'environnement en évitant > d'imprimer ce mail / Bitte drucken Sie diese Nachricht nicht aus und > helfen Sie so Logica dabei die Umwelt zu schuetzen / Por favor ajude > a Logica a respeitar o ambiente não imprimindo este correio electrónico. > > > > This e-mail and any attachment is for authorised use by the intended > recipient(s) only. It may contain proprietary material, confidential > information and/or be subject to legal privilege. It should not be > copied, disclosed to, retained or used by, any other party. If you are > not an intended recipient then please promptly delete this e-mail and > any attachment and all copies and inform the sender. Thank you. > > -- Sent from my mobile device Please help Logica to respect the environment by not printing this email / Merci d'aider Logica à préserver l'environnement en évitant d'imprimer ce mail / Bitte drucken Sie diese Nachricht nicht aus und helfen Sie so Logica dabei die Umwelt zu schuetzen / Por favor ajude a Logica a respeitar o ambiente não imprimindo este correio electrónico. This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you.