Java 未提交声明性spring事务
我有以下服务类别:Java 未提交声明性spring事务,java,spring,hibernate,spring-transactions,Java,Spring,Hibernate,Spring Transactions,我有以下服务类别: public class UserLoginServiceImpl implements UserLoginService { private UserDAO dao; public UserLoginServiceImpl(UserDAO dao) {this.dao = dao; } public User login(String userName, String password) { User u = dao.findUserByCred
public class UserLoginServiceImpl implements UserLoginService {
private UserDAO dao;
public UserLoginServiceImpl(UserDAO dao) {this.dao = dao; }
public User login(String userName, String password) {
User u = dao.findUserByCredentials(userName, password);
if (u == null) {
throw new UserNotFoundException();
}
return u;
}
public class UserManagementServiceImpl implements UserManagementService {
private UserDAO dao;
public UserManagementServiceImpl(UserDAO dao) { this.dao = dao; }
public void createUser(User u) {
dao.save(u);
}
}
我的服务接口位于com.mysystem.services包下,我的服务实现位于com.mysystem.services.impl包下
我在spring中使用hibernate作为我的jpa实现和声明性事务。我的配置文件如下所示:
UserManagementService userManagementService = context.getBean(UserManagementService.class);
userManagementService.createUser(new User("test", "test"));
UserLoginService userLogginService = context.getBean(UserLoginService.class);
User user = userLogginService.login("test", "test");
这导致login()方法抛出UserNotFoundException,因为它找不到以前由createUser()插入的用户,这意味着hibernate不会在方法调用之间刷新会话。我可以通过控制台输出验证这个表单(我可以看到hibernate的create和select语句,但不能看到insert)
为什么在调用createUser()后不久没有提交事务?我做错了什么
编辑:
使用@Transactional注释而不是声明性事务是可行的。但是,使用@Transactional对我来说不是一个选项。我需要实现声明性事务
下面是spring的调试输出:
13:03:18,174 DEBUG [main] jpa.JpaTransactionManager - Creating new transaction with name [com.mysystem.services.impl.UserManagementServiceImpl.createUser]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT
13:03:18,175 DEBUG [main] jpa.JpaTransactionManager - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@1af6a711] for JPA transaction
Hibernate:
select
nextval ('hibernate_sequence')
13:03:18,255 DEBUG [main] jpa.JpaTransactionManager - Initiating transaction commit
13:03:18,255 DEBUG [main] jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1af6a711]
13:03:18,256 DEBUG [main] jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@1af6a711] after transaction
13:03:18,263 DEBUG [main] jpa.JpaTransactionManager - Creating new transaction with name [com.mysystem.services.impl.UserLoginServiceImpl.login]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT
13:03:18,263 DEBUG [main] jpa.JpaTransactionManager - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@1533badd] for JPA transaction
Hibernate:
/*
from
com.mysystem.domain.User u
where
u.userName = :userName
and u.password = :password */ select
user0_.id as id0_,
user0_.password as password0_,
user0_.userName as userName0_
from
Users user0_
where
user0_.userName=?
and user0_.password=? limit ?
13:03:18,374 TRACE [main] sql.BasicBinder - binding parameter [1] as [VARCHAR] - test
13:03:18,374 TRACE [main] sql.BasicBinder - binding parameter [2] as [VARCHAR] - test
13:03:18,379 DEBUG [main] jpa.JpaTransactionManager - Initiating transaction commit
13:03:18,379 DEBUG [main] jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1533badd]
13:03:18,379 DEBUG [main] jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@1533badd] after transaction
你能试试这个吗
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="createUser" propagation="REQUIRES_NEW" />
</tx:attributes>
</tx:advice>
你能试试这个吗
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="createUser" propagation="REQUIRES_NEW" />
</tx:attributes>
</tx:advice>
您需要一个新交易。这会给你你需要的=“需要新的。你能试着给出反馈吗。。。也不管用。但有趣的是,当我使用@Transactional注释时,它会起作用。我猜这一定是我的配置中的某个东西,但我现在还没弄明白。嗯。。好啊你能更新你的切入点表达式com.mysystem.services.impl.*.*(..)吗?我想问题是存在的。问题:我应该在实现类的方法或接口上定义我的事务吗?我设法解决了这个问题(最后)。在我的设计中,我选择使用构造函数注入来注入EntityManagerFactory。然后在我的dao的构造函数中使用emf创建EntityManager并将其设置为dao实例的成员变量。当我将注入策略更改为使用@PersistenceContext注释时,我成功地实现了这一点。我仍然不知道为什么我最初的策略不起作用,但最终的结果是它起作用了。如果有人能解释一下,我很感兴趣。你需要一笔新的交易。这会给你你需要的=“需要新的。你能试着给出反馈吗。。。也不管用。但有趣的是,当我使用@Transactional注释时,它会起作用。我猜这一定是我的配置中的某个东西,但我现在还没弄明白。嗯。。好啊你能更新你的切入点表达式com.mysystem.services.impl.*.*(..)吗?我想问题是存在的。问题:我应该在实现类的方法或接口上定义我的事务吗?我设法解决了这个问题(最后)。在我的设计中,我选择使用构造函数注入来注入EntityManagerFactory。然后在我的dao的构造函数中使用emf创建EntityManager并将其设置为dao实例的成员变量。当我将注入策略更改为使用@PersistenceContext注释时,我成功地实现了这一点。我仍然不知道为什么我最初的策略不起作用,但最终的结果是它起作用了。如果有人能对此进行解释,我会很感兴趣。您可以执行flush(EntityManager.flush()),如果您在服务方法中创建调用后执行此操作,则用户将可以看到get方法,而不必实际提交事务。您可以执行flush(EntityManager.flush()),如果在服务方法中创建调用后执行此操作,则用户将可以看到get方法,而不必实际提交事务。