Đây là vấn đề của tôi:hành vi kỳ lạ với @Transactional (tuyên truyền = Propagation.REQUIRES_NEW)
Tôi đang chạy một lô trên một ứng dụng Java EE/Spring/Hibernate. Lô này gọi method1
. Phương thức này gọi là method2
có thể ném UserException
(một lớp mở rộng RuntimeException
). Sau đây là cách nó trông giống như:
@Transactional
public class BatchService implements IBatchService {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public User method2(User user) {
// Processing, which can throw a RuntimeException
}
public void method1() {
// ...
try {
this.method2(user);
} catch (UserException e) {
// ...
}
// ...
}
}
Các ngoại lệ được đánh bắt như việc thực hiện vẫn tiếp tục, nhưng ở phần cuối của method1
khi giao dịch được đóng một RollbackException được ném.
Đây là stack trace:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy128.method1(Unknown Source)
at batch.BatchController.method1(BatchController.java:202)
Khi method2
không ném ngoại lệ này, nó hoạt động tốt.
Những gì tôi đã cố gắng:
- Thiết
@Transactional(noRollbackFor={UserException.class}))
trênmethod1
- Hãy thử và đánh bắt trong
method2
Nhưng nó không thay đổi bất cứ điều gì.
Vì ngoại lệ được đưa vào một giao dịch khác, trong đó một trường hợp hoàn tiền xảy ra, tôi không hiểu tại sao nó không hoạt động. Tôi đã xem xét điều này: Jpa transaction javax.persistence.RollbackException: Transaction marked as rollbackOnly nhưng nó đã không thực sự giúp tôi.
Tôi sẽ rất tuyệt vời nếu ai đó có thể cho tôi một đầu mối.
Cập nhật
Tôi đã thực hiện nó hoạt động bằng cách thiết lập propagation=Propagation.REQUIRES_NEW
vào phương pháp gọi bằng method2
(mà thực sự là một trong đó là gửi các ngoại lệ). Phương pháp này được định nghĩa trong một lớp rất giống với BatchService
của tôi. Vì vậy, tôi không thấy lý do tại sao nó hoạt động trên cấp độ này và không phải trên method2
.
- tôi đã thiết
method2
như nào là chú thích@Transactional
không đưa vào tài khoản nếu phương pháp này là tin như đã nói trong tài liệu:
Chú thích @Transactional có thể được đặt trước một giao diện định nghĩa, một phương thức trên giao diện, định nghĩa lớp hoặc phương thức công khai trên một lớp.
- Tôi cũng cố gắng sử dụng
Exception
thay vìRuntimeException
(vì nó là thích hợp hơn) nhưng nó cũng không thay đổi bất cứ điều gì.
Ngay cả khi nó đang hoạt động, câu hỏi vẫn mở vì nó có hành vi lạ và tôi muốn hiểu tại sao nó không hoạt động như vậy.
Xem http://stackoverflow.com/questions/5152686/self-injection-with-spring/ để giải quyết các vấn đề có thể xảy ra. – Vadzim