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 22:36:07 GMT
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