我正在使用Hibernate + spring + @Transactionalannotations来处理我的应用程序中的事务.
事务管理器声明如下:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
Run Code Online (Sandbox Code Playgroud)
这在大多数情况下效果很好,但是我发现了一个问题,我有两种方法,都注释了@Transactional:
package temp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
public class OuterTestService {
@Autowired
private InnerTestService innerTestService;
@Transactional
public void outerMethod() {
try {
innerTestService.innerTestMethod();
} catch (RuntimeException e) {
// some code here
}
}
}
Run Code Online (Sandbox Code Playgroud)
和
package temp;
import org.springframework.transaction.annotation.Transactional;
public class InnerTestService {
@Transactional
public void innerTestMethod() throws RuntimeException {
throw new RuntimeException();
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用OuterTestService#outerMethod()时,我得到一个异常
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has …Run Code Online (Sandbox Code Playgroud) 我创建了一个创建用户帐户的服务方法.如果由于给定的电子邮件地址已经在我们的数据库中而导致创建失败,我想向用户发送一封电子邮件,说明他们已经注册:
@Transactional(noRollbackFor=DuplicateEmailException.class)
void registerUser(User user) {
try {
userRepository.create(user);
catch(DuplicateEmailException e) {
User registeredUser = userRepository.findByEmail(user.getEmail());
mailService.sendAlreadyRegisteredEmail(registeredUser);
}
}
Run Code Online (Sandbox Code Playgroud)
这不起作用.虽然我标记DuplicateEmailExcepetion为"无回滚",但第二个SQL查询(findByEmail)仍然失败,因为事务已中止.
我究竟做错了什么?
@Transactional存储库中没有注释.
hibernate ×1
java ×1
jdbctemplate ×1
postgresql ×1
rollback ×1
spring ×1
spring-boot ×1
sql ×1
transactions ×1