Frage

Ich habe nach dieser Frage gesucht, es gibt einige davon hier bei StackOverflow und Google, aber ich kann anscheinend nichts für mich zum Laufen bringen.

hier sind meine Codes Spring-Konfiguration: (Ich verwende keinen Pointcut - ich glaube, ich brauche das nicht?)

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
...
</bean>

<bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />
 ...
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>

Ich habe eine Serviceklasse:

@Service
public class ServiceImpl implements ServiceInterface 
{
    /**
     * Injected session factory
     */
    @Autowired(required=true)
    private SessionFactory sessionFactory;

    @Autowired(required=true)
    private Dao myDao;

    /**
     * {@inheritDoc}
     */
    @Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
    public void scheduleBlast(BlastParameters blastParameters) throws ServiceException 
    {
        ... do bunch of stuff ..
        myDao.persist(entity)

        if(true)
            throw new ServiceException("random error")
    }

    .. setter methods and other stuff ..
}

und eine Dao-Klasse:

public class DaoImpl implements DaoInterface
{
    @Autowired(required=true)
    private SessionFactory sessionFactory

    /**
     * {@inheritDoc}
     */
    @Transactional(propagation=Propagation.MANDATORY)
    public void persist(Entity e) throws DaoException
    {
        try
        {
            sessionFactory.getCurrentSession().persist(e);
        }
        catch(Exception ex)
        {
            throw new DaoException(ex);
        }
    }


    .. setter methods and other stuff ..
}

Einige unnötige Details werden entfernt (z. B. fehlender Setter usw.). Nehmen Sie an, dass der Code einwandfrei funktioniert.

Mein Problem mit dem oben Gesagten ist, dass beim Hinzufügen der zufälligen Ausnahmezeile für das Auslösen kein Rollback durchgeführt wird und das durch das DAO beibehaltene Objekt in der Datenbank verbleibt.

Ich verwende Spring 3.1 und Hibernate 3.6 (da in Spring 3.1 ein Fehler mit Hibernate 4.0 aufgetreten ist)

Gedanken?

Danke

War es hilfreich?

Lösung 2

Ich habe die Ursache meines Problems gefunden und erklärt, warum die Transaktion (scheinbar) nicht ordnungsgemäß verwaltet wurde.

Irgendwo in meinem Code

/**
 * {@inheritDoc}
 */
@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
public void doWork(Parameters param) throws ServiceException 
{
    ... do bunch of stuff ..
    myDao1.persist(entity)

    -- Some logic here --

    ... do bunch of stuff ..
    myDao2.persist(entity2)

    if(true)
        throw new ServiceException("random error")
}
{
Query query = sessionFactory.getCurrentSession().createSQLQuery(queryText);
query.executeUpdate();

Und da keine Hibernate-Abfrage verwendet wird und stattdessen die SQL-Rohausführung verwendet wird, wurde ein Flush aufgerufen, und daher werden alle vor dem Aufruf ausgeführten Arbeiten zusammen mit festgeschrieben es.

Ich überarbeite den Logikfluss, um diese Logik zu berücksichtigen und sicherzustellen, dass die Transaktion ordnungsgemäß verwaltet wird.Die Verwendung von Raw-SQL kann ein Hinweis darauf sein, dass etwas nicht stimmt. Dies war aufgrund der Dinge, die der Dienst zu erreichen versucht, und zur Verbesserung der Leistung des Dienstes erforderlich.

Andere Tipps

Dies ist das beabsichtigte Verhalten der Transaktionsverwaltung. Das Standardverhalten für @Transactional ist das Rollback nur für Laufzeitausnahmen. Wenn Sie möchten, dass Ihre Inhalte nach dem Auslösen von DaoException zurückgesetzt werden, fügen Sie sie der Liste der Rollback-Ausnahmen hinzu.Vergessen Sie nicht, auch RuntimeException einzuschließen. Versuchen Sie Folgendes in der Dao-Klasse @Transactional (propagation= Propagation.Mandatory, rollbackFor= {RuntimeException.class, DaoException.class})

Versuchen Sie, die Annotation @Transactional aus der DaoImpl-Klasse zu entfernen.Ich vermute, dass die Transaktion festgeschrieben wird, wenn sie diese Transaktionsgrenze (DaoImpl) überschreitet.Ich hatte gemischten Erfolg mit diesem Setup.Sie können verschiedene Transaktionsansätze für die "innere" Transaktion ausprobieren.

Sie können auch die Protokollierung von Frühjahrstransaktionen aktivieren.Es denkt seine Kategorie org.springframework.transaction oder so.Auf diese Weise sehen Sie genau, was es tut, um Transaktionen zurückzusetzen und festzuschreiben ...

Sie haben keinen dieser JDBC-Treiber, die sich standardmäßig im AUTOCOMMIT-Modus befinden, oder?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top