Question

Je l'ai cherché autour de cette question, il y a un certain nombre d'entre eux ici sur StackOverflow et Google, mais je ne peux pas sembler obtenir quoi que ce soit de travailler pour moi.

voici mes codes config Spring: (je n'utilise pas pointcut - Je pense que je ne besoin?)

<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"/>

J'ai une classe de service:

@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 ..
}

et une classe Dao:

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 ..
}

Quelques détails inutiles sont éliminés (par exemple setter manquant., Etc.), on suppose que le code fonctionne parfaitement bien.

Mon problème avec ce qui précède est que lorsque j'ai ajouté la ligne d'exception aléatoire de jet, il n'a pas rollback, l'être de l'objet a persisté à travers les séjours de DAO dans la db.

J'utilise Spring 3.1 et Hibernate 3.6 (parce qu'il y avait un bug avec Hibernate 4.0 sur Spring 3.1)

Pensées?

Merci

Était-ce utile?

La solution 2

J'ai trouvé la cause de mon problème et pourquoi la transaction (apparemment) pas géré correctement.

Quelque part dans mon 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")
}

La partie où il est dit « - une certaine logique ici - », il y avait une certaine logique fait que les utilisations SQL premières et appel à exécuter la mise à jour:

Query query = sessionFactory.getCurrentSession().createSQLQuery(queryText);
query.executeUpdate();

Et parce qu'il est de ne pas utiliser la requête Hibernate, et au lieu d'utiliser l'exécution SQL brute, il a provoqué une chasse d'eau à appeler et donc sera engagé tout travail effectué avant l'appel avec il.

Je re-travailler le flux de la logique pour tenir compte de cette logique pour faire transaction vous est gérée correctement. Lors de l'utilisation de SQL brute pourrait être une indication qu'il ya quelque chose de mal -. Il était quelque chose de nécessaire à faire en raison des choses que l'essai de service à accomplir et d'améliorer la performance du service

Autres conseils

C'est le comportement prévu de la gestion des transactions. Le comportement par défaut pour @Transactional est rollback que des exceptions d'exécution. Si vous voulez que votre truc à rollback après avoir jeté DaoException puis l'ajouter à la liste d'exceptions rollback. Ne pas oublier d'inclure également RuntimeException aussi. Essayez ce qui suit sur la classe Dao @Transactional (propagation = Propagation.Mandatory, rollbackFor = {RuntimeException.class, DaoException.class})

Essayez raye la mention @Transactional de la classe DaoImpl. Je soupçonne que ce qui pourrait se produire est que la transaction est commise quand elle traverse en arrière sur cette limite de transaction (DaoImpl). J'ai eu un succès mitigé avec cette configuration. Vous pouvez essayer une transaction différentes approches de la transaction « intérieure ».

L'autre chose que vous pouvez faire est de mettre la journalisation des transactions de printemps. Il pense que sa catégorie org.springframework.transaction ou quelque chose. De cette façon, vous verrez exactement ce qu'il fait w.r.t à faire reculer et engager des transactions ...

vous n'avez pas un de ces pilotes JDBC qui sont en mode AUTOCOMMIT par défaut, pensez-vous?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top