0

I'm working about a identity, access and role management with SDN 2.1.0-RC4 without AspectJ. This system aims to manage around 120 000 users and data is extracted from legacy and HR applications. I have from 500 to 30000 updates/day, so performance can be a touchy subject I ran some workbenches with default configuration.

I used a very simple and stupid way. A simple class

@TypeAlias("event")
@NodeEntity
public class Event {

    @GraphId
    private Long graphId;

    @Indexed
    private Long eventId;

    @RelatedTo(type="PREVIOUS_EVENT", direction=Direction.OUTGOING)
    private Event previous;

    private String description;

        /.../
}

and I insert data one by one

    /.../
/**
 * 
 */
public void loadAllData() {

    Event root = new Event();
    root.setEventId(0L);
    root.setDescription("ROOT");

    repository.save(root);
    Event curr = root;


    for(int i = 0; i< SIZE; i ++) {
        curr = insertData(curr, i );
    }
}


/**
 * @param curr
 * @param i
 * @return
 */
public Event insertData(Event curr, int i) {
    long lastTime = System.currentTimeMillis();
    Event evt = new Event();
    evt.setEventId(curr.getEventId()+1);
    evt.setPrevious(curr);
    evt.setDescription("event #"+i);
    repository.save(evt);
    curr = evt;
    delais[i] = System.currentTimeMillis() - lastTime;
    return curr;

}
/.../

I test several by overloading theses methods

1) use of @Transactional

@Override
@Transactional
public Event insertData(Event curr, int i) {
    return super.insertData(curr, i);
}

2) Use of neo4j transaction

@Override
public void loadAllData() {
    gds = getContext().getBean(GraphDatabaseService.class);
    super.loadAllData();
}       

@Override
public Event insertData(Event curr, int i) {                
    Transaction tx = gds.beginTx();
    try {
        curr = super.insertData(curr, i);
        tx.success();
    } catch(Exception e) {
        tx.failure();
    } finally {
        tx.finish();
    }
    return curr;

}

I know benchmark are a trolling subject and it's not what I want. So take theses values as they are: a stupid test

Results

JtaTransactionManager

Mean 47,20 ms, Min 21,00 ms, Max 425,00 ms

GraphDatabaseService

Mean 0,90 ms, Min 0,00 ms, Max 3,00 ms

JtaTransactionManager is very slow compared to native neo4j server, but JtaTransactionManager is a global and ambitious TransactionManager.

My purpose is how to lighten or create a custom transactionManager with less ambition, a smaller scope but still using the @Transactional annotation ?

May be I've missed something ?

Thanks you for any potential help or advice.

PS: my configuration

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:annotation-config/>
    <context:spring-configured/>

    <context:component-scan base-package="benchmark"/>

    <neo4j:repositories base-package="benchmark.repository"/>
    <neo4j:config graphDatabaseService="graphDatabaseService"/>


    <bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase" 
      destroy-method="shutdown">
         <constructor-arg index="0" value="data/benchmark.db" />
    </bean>


</beans>

Marc DeXeT

4

1 回答 1

2

您使用两个完全不同的事务批量大小。

使用“neo4j”TM,您可以使用一个全局 tx 范围,其中包含您的所有更新(也就是数百或数千个操作)。

有了 tx,@Transactional您就拥有了单个操作的 tx 范围。因此,事务的开销会为每个操作添加一次,而不是一次。

所以试着在周围放一个@Transactional loadAllData()

此外,为了获得更高的插入速度,请尝试使用template.createRelationshipBetween(...., duplicate=true)而不是evt.setPrevious(curr). 所以你跳过所有的增量检测和重复消除。

于 2012-10-22T15:16:59.283 回答