2016-11-09 3 views
2

Ich habe derzeit ein Setup, bei dem Daten in eine Datenbank eingefügt und in Solr indiziert werden. Diese beiden Schritte werden in eine federverwaltete Transaktion über die Annotation @Transaction eingebunden. Was ich bemerkt habe ist, dass der Frühling-data-solr ein Update mit den folgenden Parametern ausgibt, wenn die Transaktion geschlossen wird: params {commit = true & SoftCommit = false & waitSearcher = true}Spring Data Solr @Transaction Commits

@Transactional 
public void save(Object toSave){ 
    dbRepository.save(toSave); 
    solrRepository.save(toSave); 
} 

Die Rate der Commits in solr ist ziemlich hoch, also möchte ich idealerweise Daten an den solr-Index senden und in regelmäßigen Abständen solr automatisch committen. Ich habe die AutoCommit (und AutoSoftCommit) in meiner solrconfig.xml gesetzt, aber da spring-data-solr diese Commit-Parameter sendet, wird jedes Mal ein hartes Commit ausgeführt.

Ich bin mir bewusst, dass ich auf die SolrTemplate-API zugreifen und Commits manuell ausstellen kann. Ich möchte den Aufruf von solr repository.save in einer im Frühjahr verwalteten Transaktion behalten, wenn möglich. Gibt es eine Möglichkeit, die Parameter zu ändern, die beim Commit an Solr gesendet werden?

Antwort

0

Die Art, wie ich etwas Ähnliches getan habe, ist eine benutzerdefinierte Repository-Implementierung der Speichermethoden zu erstellen.

Schnittstelle für das Repository:

public interface FooRepository extends SolrCrudRepository<Foo, String>, FooRepositoryCustom { 
} 

Schnittstelle für die benutzerdefinierten Überschreibungen:

public interface FooRepositoryCustom { 
    public Foo save(Foo entity); 
    public Iterable<Foo> save(Iterable<Foo> entities); 
} 

Implementierung der benutzerdefinierten Überschreibungen:

public class FooRepositoryImpl { 

    private SolrOperations solrOperations; 

    public SolrSampleRepositoryImpl(SolrOperations fooSolrOperations) { 
     this.solrOperations = fooSolrOperations; 
    } 

    @Override 
    public Foo save(Foo entity) { 
     Assert.notNull(entity, "Cannot save 'null' entity."); 
     registerTransactionSynchronisationIfSynchronisationActive(); 
     this.solrOperations.saveBean(entity, 1000); 
     commitIfTransactionSynchronisationIsInactive(); 
     return entity; 
    } 

    @Override 
    public Iterable<Foo> save(Iterable<Foo> entities) { 
     Assert.notNull(entities, "Cannot insert 'null' as a List."); 

     if (!(entities instanceof Collection<?>)) { 
      throw new InvalidDataAccessApiUsageException("Entities have to be inside a collection"); 
     } 

     registerTransactionSynchronisationIfSynchronisationActive(); 
     this.solrOperations.saveBeans((Collection<? extends T>) entities, 1000); 
     commitIfTransactionSynchronisationIsInactive(); 
     return entities; 
    } 

    private void registerTransactionSynchronisationIfSynchronisationActive() { 
     if (TransactionSynchronizationManager.isSynchronizationActive()) { 
      registerTransactionSynchronisationAdapter(); 
     } 
    } 

    private void registerTransactionSynchronisationAdapter() { 
     TransactionSynchronizationManager.registerSynchronization(SolrTransactionSynchronizationAdapterBuilder 
       .forOperations(this.solrOperations).withDefaultBehaviour()); 
    } 

    private void commitIfTransactionSynchronisationIsInactive() { 
     if (!TransactionSynchronizationManager.isSynchronizationActive()) { 
      this.solrOperations.commit(); 
     } 
    } 
} 

und Sie müssen auch eine SolrOperations schaffen Bean für den richtigen Solr-Kern:

@Configuration 
public class FooSolrConfig { 

    @Bean 
    public SolrOperations getFooSolrOperations(SolrClient solrClient) { 
     return new SolrTemplate(solrClient, "foo"); 
    } 
} 

Fußnote: Auto Commit ist (meiner Meinung nach) konzeptionell mit einer Transaktion inkompatibel. Ein Auto-Commit ist ein Versprechen von solr, dass es versuchen wird, es innerhalb eines bestimmten Zeitlimits auf die Festplatte zu schreiben. Viele Dinge können jedoch verhindern, dass tatsächlich etwas passiert - ein rechtzeitiger Strom- oder Hardwarefehler, Fehler zwischen dem Dokument und dem Schema usw. Aber der Client wird nicht wissen, dass solr sein Versprechen nicht eingehalten hat, und die Transaktion wird einen Erfolg sehen, wenn es ist tatsächlich gescheitert.

Verwandte Themen