当前位置: 首页 > 知识库问答 >
问题:

单个Spring@Transaction中的两个dao方法

荀俊迈
2023-03-14
@Transactional(propagation=Propagation.REQUIRES_NEW,value="txManager",rollbackFor=TransactionUnSuccessException.class)
public Account makeTransaction(Transaction transaction, String userName)
        throws TransactionUnSuccessException {
    Account account = null;
    account = transferDao.makeTransaction(transaction, userName);
    return account;
}
@Repository
public class TransferDao extends HibernateDaoSupport {
@Autowired
private SessionFactory sessionFactory;



public Account makeTransaction(Transaction transaction, String userName)
        throws TransactionUnSuccessException {
    HibernateTemplate hibernateTemplate = getHibernateTemplate();
    Account account = null;
    Session session = hibernateTemplate.getSessionFactory().openSession();
    //session.beginTransaction();
    updateSelfAccount(transaction, userName, session);
    account = updateAnotherAcccount(transaction, session);
    //session.getTransaction().commit();
    return account;
}

private void updateSelfAccount(Transaction transaction, String userName,
        Session session) {
    User currentUser = null;
    System.out.println("TransferDao.updateSelfAccount()" + transaction);

    Query query = session.createQuery("from User where userName=:userName");
    query.setParameter("userName", userName);
    currentUser = (User) query.list().get(0);

    currentUser.getAccount().getTransactions().add(transaction);
    currentUser.getAccount().setAvailableBalance(
            currentUser.getAccount().getAvailableBalance()
                    - transaction.getAmount());
    transaction.setTransAccount(currentUser.getAccount());
    session.save(transaction);
    session.update(currentUser.getAccount());
    session.update(currentUser);


private Account updateAnotherAcccount(Transaction transaction,
        Session session) throws TransactionUnSuccessException {

       Account account = null;
    try {
        Query query = session
                .createQuery("from Account where accNo=:accNo");
        query.setParameter("accNo", transaction.getToAcc());
        account = (Account) query.list().get(0);
        if (account.getAvailableBalance() < 5000) {
            account.setAvailableBalance(account.getAvailableBalance()
                    + transaction.getAmount());
            account.getTransactions().add(transaction);
            transaction.setTransAccount(account);
            session.save(transaction);
            session.update(account);
        } else {
            throw new TransactionUnSuccessException();
        }
    } catch (TransactionUnSuccessException te) {
        te.printStackTrace();
    }

    return account;
}
}
}

Xml配置:

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

如果这两个方法中的任何一个(updateSelfAccount,updateAnotherAcccount)失败,则整个事务都应该回滚。但是它不能回滚给定的异常,即使我不确定这一切都发生在一个事务中。请指正。

共有1个答案

袁俊弼
2023-03-14

使用@Transactional注释的目的是您的代码不应该处理事务本身。在代码示例中使用@transactional,因此不必执行以下操作:

session.beginTransaction();

您还用其他一些东西正确地设置了spring

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

<tx:annotation-driven transaction-manager="transactionManager"/>

通常,sessionFactory在dao中是@Autowired的,为了方便地访问会话,您可以这样做

 类似资料:
  • 问题内容: 继上一个问题DAO和Service层(JPA / Hibernate + Spring)之后 ,我决定在使用JPA / Hibernate,Spring和Wicket的应用程序中(至少在开始时)仅对我的数据层使用一个DAO。提出了使用通用CRUD方法的方法,但是我不太确定如何使用JPA来实现。您能否举个例子或分享有关此的链接? 问题答案: 这是一个示例界面: 和一个实现:

  • 有可能将两个DAO组合成一个服务方法吗? 我想创建一个泛型方法,它将根据输入参数选择正确的DAO。现在我想出的是从服务对象外部接受Dao的方法。但这需要在控制器中初始化适当的Dao,这有点难看...

  • 我正在处理一些遗留代码,其中所有Spring DAO都用@Transactional注释注释。现在我有一个业务需求,我需要在我的服务层中调用两个不同的DAO,如果事务在任何时候失败,就回滚它。 如何在Spring5中实现这一点,而不从DAO中删除@Transactional注释,并且仍然从服务层使用它们。我认为下面的代码不起作用,因为每个DAO中的事务彼此独立。 非常感谢提前。

  • 意味着我需要跟踪原始表,类似于用值和已经进行的操作记录表 指导我在春靴中实现这一点。

  • 问题内容: 这有道理吗? 假设我需要从数据库中获取一个与另一个对象有关系的对象(由数据库中的外键以及域对象中的组合表示)。如果在我的第一个DAO中,我获取对象1的数据,则调用对象2的dao,最后(从第一个DAO中,调用对象1中的setter,并为其提供先前获取的对象2)。 我知道我可以代替加入连接,但是对我来说,断开功能耦合似乎更合乎逻辑(这就是为什么我对从另一个调用一个dao持怀疑态度)。还是应