服务层上的@Transactional没有回滚Spring MVC + Hibernate

时间:2016-04-30 23:28:23

标签: spring hibernate transactional

我有3个类(服务层中的UserSrvImpl,dao(存储库)层中的MailDaoImpl和UserDaoImpl)。在我的服务层(UserSrvImpl)中,我有一个从MailDaoImpl调用方法的方法和一个来自UserDaoImpl的方法。这两个dao方法必须将对象保存在2个不同的表中。这两个表具有OneToOne关系。我的问题是当第一次插入成功而第二次插入失败时,没有回滚。我一周以来一直在努力解决这个问题。我应用了我在谷歌找到的所有解决方案,但仍然没有成功。你能帮我个忙吗? 这是我的服务层:

@Service
public class UserSrvImpl implements IUserSrv {
@Autowired
private IUserDao userDao;
@Autowired
private IMailDao mailDao;

@Override
@Transactional
public boolean create(UserDto userDto) {
    boolean result = false;
    try {
        User userToSave = transformDtoToEntity(userDto);
        MailToken mailToken = createMailTokenForNewUser(userToSave);

        userToSave.setMailToken(mailToken);
        if (mailDao.createMailToken(mailToken)) {
            result = userDao.create(userToSave);
        }

    } catch (Exception ex) {

    }
    return result;
}

该服务正在调用dao的方法mailDao.createMailToken和userDao.create。如果第一个成功而第二个失败,则数据库中的第一个表上没有回滚。 下面是MailDao中的代码:

@Repository
public class MailDao implements IMailDao {
@Autowired
private SessionFactory sessionFactory;

public Session getSession() {
    Session sess = this.sessionFactory.getCurrentSession();
    if (sess == null) {
        sess = this.sessionFactory.openSession();
    }
    return sess;
}

@Override
public boolean createMailToken(MailToken mailToken) {
    try {
        getSession().save(mailToken);
        return true;
    } catch (HibernateException ex) {

    } catch (Exception ex) {
        // TODO: handle exception
    }
    return false;
}

以下是UserDaoImpl中的代码:

@Repository
public class UserDaoImpl implements IUserDao {

@Autowired
private SessionFactory sessionFactory;

public Session getSession() {
    Session sess = this.sessionFactory.getCurrentSession();
    if (sess == null) {
        sess = this.sessionFactory.openSession();
    }
    return sess;
}

@Override
public boolean create(User userToSave) {
    try {
        getSession().save(userToSave);
        return true;
    } catch (HibernateException ex) {
        ex.printStackTrace();

    } catch (Exception ex) {
        // TODO: handle exception
    }

    return false;
}

这是我的弹簧配置:

<bean id="hibernate5AnnotatedSessionFactory"
    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="packagesToScan">
        <array value-type="java.lang.String">
            <value>com.pointsante.dao.domaine</value>
        </array>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
        </props>
    </property>
</bean>
<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

请告诉我为什么服务层中方法的@Transactional不起作用。谢谢。

1 个答案:

答案 0 :(得分:0)

您应该使用HibernateTransactionManager而不是DataSourceTransactionManager。

使用

<bean id="transactionManager"
    class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

而不是

<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

还要检查调用服务的位置。如果从服务类本身调用它,则不会使用处理事务管理的代理。