ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christopher Lamey <cla...@localmatters.com>
Subject Re: Performance question
Date Wed, 09 Jan 2008 23:51:51 GMT
Those kind of days are no fun, that's for sure:)

Take a look at the Spring docs for an example of the transaction management
config.  Section 9.5.2 has an example:

http://static.springframework.org/spring/docs/2.5.x/reference/transaction.ht
ml#transaction-declarative-first-example

Basically, you setup a tx:advice that setups up a transaction manager to
work on specified methods.  Then you have an aop:config that specifies an
expression pattern to apply against a set of classes which ties in the
tx:advice.  The DataSourceTransactionManager transaction manager essentially
wraps around the DataSource for you.  There are other transaction managers
if you want to use them.

Their docs do a detailed job describing what's going on, it's very easy and
nice because your DAO code doesn't have to worry about explicitly handling
transactions and batches.

BTW, this style of transaction management declaration was new for Spring
2.0.  So you'll see a different style for any older examples.  This new way
is better, so ignore the old ones.

Cheers,
Chris

On 1/9/08 3:43 PM, "Brian Parkinson" <parki@avaning.com> wrote:

> Thanks Christoper - it's end of day here (frustrating one :-) and so
> I'll tackle these tomorrow - appreciated.
> 
> Below are my spring config setup - if anyone can point me directions on
> how to set up the transaction handling in Spring (which I do *not* have)
> this would also be appreciated.
> 
> Or any other suggestions - I'm new to iBATIS; it's been working out
> great so far, so hopefully can get these numbers down to reasonable.
> 
> Cheers,
> 
> parki...
> 
> 
> <bean id="mapConfig"
> class="org.springframework.core.io.ClassPathResource">
> <constructor-arg>
> 
> <value>com/ecobee/foundation/dao/ibatis/SqlMapConfig.xml</value>
> </constructor-arg>
> </bean>
> 
> <bean id="dataSource"
> class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
> <property name="driverClassName"
> value="com.mysql.jdbc.Driver" />
> <property name="url" value="jdbc:mysql:///ecobee" />
> <property name="username" value="ecobee" />
> <property name="password" value="ecobee" /> 
> <property name="initialSize" value="2" />
> <property name="maxActive" value="5" /> 
> <property name="maxIdle" value="2" />
> </bean>
> 
> <bean id="sqlMapClient"
> class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
> <property name="dataSource" ref="dataSource" />
> <property name="configLocation" ref="mapConfig" />
> </bean>
> 
> -----Original Message-----
> From: Christopher Lamey [mailto:clamey@localmatters.com]
> Sent: Wednesday, January 09, 2008 4:36 PM
> To: user-java@ibatis.apache.org
> Subject: Re: Performance question
> 
> Hello,
> 
> A transaction can get to a certain size and start to build up a big
> enough
> rollback segment or two that it slows the whole thing down.  So you
> might
> want to consider breaking up your inserts into smaller transactions and
> see
> if that helps your speed.  I usually make the size of the commit batches
> a
> runtime variable that I can play with to see what's best.
> 
> Also, what kind of indexes are involved and how much data is in the
> tables?
> It looks like you have a dozen or so tables with foreign keys, so that's
> a
> bunch of indexes to update.  If you have more indexes on the tables, it
> just
> adds to slow writes.
> 
> It also depends on how your db is configured.  For example, in Postgres
> you
> can control whether or no fsyncs are forced, full page writes occur, how
> big
> the write ahead buffers are, how many checkpoint logfile segments are
> used,
> etc.  It also depends on the I/O subsystem where the actual db files
> live -
> the slower the disk, the slower your db writes will be.
> 
> I'm also wondering why you have explicit transaction handling in your
> DAO
> when you're using Spring?  Am I understanding your setup correctly?
> IIRC,
> if you use the Spring SqlMapClient, iBATIS assumes you're using an
> external
> transaction manager and so explicit calls to startTransaction(),
> startBatch(), etc. have no effect.  And so if you have no declarative
> transaction handling setup in Spring, there is no transaction management
> going on.
> 
> Try throwing an new RuntimeException("Forcing transaction rollback")
> halfway
> through that method.  See if everything before the exception is throw is
> actually handled and rolled back.
> 
> Cheers,
> Chris
> 
> On 1/9/08 3:16 PM, "Brian Parkinson" <parki@avaning.com> wrote:
> 
>> Hello:
>> 
>>  
>> 
>> I am using iBATIS, and it's working out well for me, but have run into
> a
>> performance issue, and wondering if anyone can help.
>> 
>>  
>> 
>> The object I am trying to persist is pretty complicated - it's an
> object
>> which contains a bunch of child objects, which contain children, etc.
>> The save method in the DAO (I am using the Spring DAO base class) is
>> pretty long and complicated, as it has to save each child object (or
>> list of child objects) separately. Example code is at the bottom of
> this
>> email.
>> 
>>  
>> 
>> I have put the whole thing into a transaction as well as doing the
> whole
>> thing in a batch, which I expect should have some performance
>> improvements.
>> 
>>  
>> 
>> When I run a performance test, I am finding that the insert (doSave)
> is
>> extremely slow - averaging about 100 ms (this after "priming" the test
>> with 1000 transactions, and running the test over an additional 1000).
>> 
>>  
>> 
>> So, my question is - can anyone make any suggestions on how to speed
>> this up - clearly 100ms is too long a time to persist this data.
>> 
>>  
>> 
>> Any help would be greatly appreciated.
>> 
>> 
>> Regards,
>> 
>>  
>> 
>> parki...
>> 
>>  
>> 
>>  
>> 
>>       private void doSave(Thermostat thermostat) throws Exception
>> 
>>       {
>> 
>>             try
>> 
>>             {   
>> 
>>                   getSqlMapClient().startTransaction();
>> 
>>                   getSqlMapClient().startBatch();
>> 
>>                 
>> 
>>                   int thermostatId = (Integer)
>> getSqlMapClientTemplate().insert("Thermostat.insert", thermostat);
>> 
>>                 
>> 
>>                   Location location = thermostat.getLocation();
>> 
>>                   location.setThermostatId(thermostatId);
>> 
>>                   getSqlMapClientTemplate().insert("Location.insert",
>> location);
>> 
>>  
>> 
>>                   Setting setting = thermostat.getSetting();
>> 
>>                   setting.setThermostatId(thermostatId);
>> 
>>                   getSqlMapClientTemplate().insert("Setting.insert",
>> setting);
>> 
>>                 
>> 
>>                   ContractorInfo contractorInfo =
>> thermostat.getContractorInfo();
>> 
>>                   contractorInfo.setThermostatId(thermostatId);
>> 
>>  
>> getSqlMapClientTemplate().insert("ContractorInfo.insert",
>> contractorInfo);
>> 
>>  
>> 
>>                   List<EquipmentInfo> equipmentInfos =
>> thermostat.getEquipmentInfos();
>> 
>>                   for(EquipmentInfo equipmentInfo : equipmentInfos)
>> 
>>                   {
>> 
>>                         equipmentInfo.setThermostatId(thermostatId);
>> 
>>  
>> getSqlMapClientTemplate().insert("EquipmentInfo.insert",
> equipmentInfo);
>> 
>>                   }
>> 
>>                 
>> 
>>                   InternetConfig internetConfig =
>> thermostat.getInternetConfig();
>> 
>>                   internetConfig.setThermostatId(thermostatId);
>> 
>>  
>> getSqlMapClientTemplate().insert("InternetConfig.insert",
>> internetConfig);
>> 
>>  
>> 
>>                   WifiConfig wifiConfig = thermostat.getWifiConfig();
>> 
>>                   wifiConfig.setThermostatId(thermostatId);
>> 
>> 
> getSqlMapClientTemplate().insert("WifiConfig.insert",
>> wifiConfig);
>> 
>>                 
>> 
>>                   List<Zone> zones = thermostat.getZones();
>> 
>>                   for(Zone zone : zones)
>> 
>>                   {
>> 
>>                         zone.setThermostatId(thermostatId);
>> 
>> 
> getSqlMapClientTemplate().insert("Zone.insert",
>> zone);
>> 
>>                   }
>> 
>>                 
>> 
>>                   Program program = thermostat.getProgram();
>> 
>>                   program.setThermostatId(thermostatId);
>> 
>>                 
>> 
>>                   int programId = (Integer)
>> getSqlMapClientTemplate().insert("Program.insert", program);
>> 
>>                 
>> 
>>                   List<CalendarEvent> calendarEvents =
>> program.getCalendarEvents();
>> 
>>                   for(CalendarEvent calendarEvent : calendarEvents)
>> 
>>                   {
>> 
>>                         calendarEvent.setProgramId(programId);
>> 
>>  
>> getSqlMapClientTemplate().insert("CalendarEvent.insert",
> calendarEvent);
>> 
>>                   }
>> 
>>                 
>> 
>>                   List<Climate> climates = program.getClimates();
>> 
>>                   for(Climate climate : climates)
>> 
>>                   {
>> 
>>                         climate.setProgramId(programId);
>> 
>>                         int climateId = (Integer)
>> getSqlMapClientTemplate().insert("Climate.insert", climate);
>> 
>>                 
>> 
>>                         List<ClimateZone> climateZones =
>> climate.getClimateZones();
>> 
>>                         for(ClimateZone climateZone : climateZones)
>> 
>>                         {
>> 
>>                               climateZone.setClimateId(climateId);
>> 
>>                               climateZone.setProgramId(programId);
>> 
>>  
>> getSqlMapClientTemplate().insert("ClimateZone.insert", climateZone);
>> 
>>                         }
>> 
>>                   }
>> 
>>                 
>> 
>>                   List<Period> periods = program.getPeriods();
>> 
>>                   for(Period period : periods)
>> 
>>                   {
>> 
>>                         period.setProgramId(programId);
>> 
>>  
>> getSqlMapClientTemplate().insert("Period.insert", period);
>> 
>>                   }
>> 
>>                 
>> 
>>                   getSqlMapClient().executeBatch();
>> 
>>                   getSqlMapClient().commitTransaction();
>> 
>>             }
>> 
>>             finally
>> 
>>             {
>> 
>>                   getSqlMapClient().endTransaction();
>> 
>>             }
>> 
>>       }
>> 
>>       
>> 
>>  
>> 
>>  
>> 
>>  
>> 
> 


Mime
View raw message