我是Spring Transaction的新手.我发现的一些事情很奇怪,可能我确实理解了这一点.我希望在方法级别有一个事务处理,并且我在同一个类中有一个调用方法,看起来它不喜欢它,它必须从单独的类调用.我不明白这是怎么可能的.如果有人知道如何解决这个问题,我将不胜感激.我想使用相同的类来调用带注释的事务方法.
这是代码:
public class UserService {
@Transactional
public boolean addUser(String userName, String password) {
try {
// call DAO layer and adds to database.
} catch (Throwable e) {
TransactionAspectSupport.currentTransactionStatus()
.setRollbackOnly();
}
}
public boolean addUsers(List<User> users) {
for (User user : users) {
addUser(user.getUserName, user.getPassword);
}
}
}
Run Code Online (Sandbox Code Playgroud) 从同一个bean的另一个方法调用缓存方法时,Spring缓存不起作用.
这是一个以清晰的方式解释我的问题的例子.
组态:
<cache:annotation-driven cache-manager="myCacheManager" />
<bean id="myCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="myCache" />
</bean>
<!-- Ehcache library setup -->
<bean id="myCache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:shared="true">
<property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>
<cache name="employeeData" maxElementsInMemory="100"/>
Run Code Online (Sandbox Code Playgroud)
缓存服务:
@Named("aService")
public class AService {
@Cacheable("employeeData")
public List<EmployeeData> getEmployeeData(Date date){
..println("Cache is not being used");
...
}
public List<EmployeeEnrichedData> getEmployeeEnrichedData(Date date){
List<EmployeeData> employeeData = getEmployeeData(date);
...
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
aService.getEmployeeData(someDate);
output: Cache is not being used
aService.getEmployeeData(someDate);
output:
aService.getEmployeeEnrichedData(someDate);
output: Cache is not being used
Run Code Online (Sandbox Code Playgroud)
该getEmployeeData方法调用使用缓存employeeData …
有可能在Spring中获取给定对象的代理吗?我需要调用子类的函数.但是,显然,当我直接打电话时,方面不适用.这是一个例子:
public class Parent {
public doSomething() {
Parent proxyOfMe = Spring.getProxyOfMe(this); // (please)
Method method = this.class.getMethod("sayHello");
method.invoke(proxyOfMe);
}
}
public class Child extends Parent {
@Secured("president")
public void sayHello() {
System.out.println("Hello Mr. President");
}
}
Run Code Online (Sandbox Code Playgroud)
我找到了实现这一目标的方法.它有效,但我认为不是很优雅:
public class Parent implements BeanNameAware {
@Autowired private ApplicationContext applicationContext;
private String beanName; // Getter
public doSomething() {
Parent proxyOfMe = applicationContext.getBean(beanName, Parent.class);
Method method = this.class.getMethod("sayHello");
method.invoke(proxyOfMe);
}
}
Run Code Online (Sandbox Code Playgroud) 这是我的问题:
我正在Java EE/Spring/Hibernate应用程序上运行批处理.这个批次调用了method1.这个方法调用一个method2可以抛出的UserException(一个类扩展RuntimeException).这是它的样子:
@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) {
// ...
}
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
在执行继续时捕获异常,但在method1事务关闭结束时抛出RollbackException.
这是堆栈跟踪:
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 …Run Code Online (Sandbox Code Playgroud) 我在Spring中异步调用方法时遇到麻烦,此时调用程序是一个从外部系统接收通知的嵌入式库.代码如下所示:
@Service
public class DefaultNotificationProcessor implements NotificationProcessor {
private NotificationClient client;
@Override
public void process(Notification notification) {
processAsync(notification);
}
@PostConstruct
public void startClient() {
client = new NotificationClient(this, clientPort);
client.start();
}
@PreDestroy
public void stopClient() {
client.stop();
}
@Async
private void processAsync(Notification notification) {
// Heavy processing
}
}
Run Code Online (Sandbox Code Playgroud)
的NotificationClient内部具有在它接收到来自另一系统的通知的线程.它接受一个NotificationProcessor构造函数,它基本上是将对通知进行实际处理的对象.
在上面的代码中,我将Spring bean作为处理器,并尝试使用@Async注释异步处理通知.但是,似乎通知在与使用的通道相同的线程中处理NotificationClient.实际上,@Async被忽略了.
我在这里错过了什么?
在编写事务方法时@Async,不可能捕获@Transactional异常.就像ObjectOptimisticLockingFailureException,因为在例如事务提交期间它们被抛出方法本身之外.
例:
public class UpdateService {
@Autowired
private CrudRepository<MyEntity> dao;
//throws eg ObjectOptimisticLockingFailureException.class, cannot be caught
@Async
@Transactional
public void updateEntity {
MyEntity entity = dao.findOne(..);
entity.setField(..);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我一般可以捕获@Async例外如下:
@Component
public class MyHandler extends AsyncConfigurerSupport {
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (ex, method, params) -> {
//handle
};
}
}
Run Code Online (Sandbox Code Playgroud)
但是我更愿意以不同的方式处理给定的异常,只要它发生在UpdateService.
问:我怎样才能抓住它里面的UpdateService?
是唯一的机会:创建一个额外的@Service包装UpdateService并有一个try-catch块?或者我可以做得更好吗?
我试图理解为什么这段代码不起作用
在组件中:
@PostConstruct
public void runAtStart(){
testStream();
}
@Transactional(readOnly = true)
public void testStream(){
try(Stream<Person> top10ByFirstName = personRepository.findTop10ByFirstName("Tom")){
top10ByFirstName.forEach(System.out::println);
}
}
Run Code Online (Sandbox Code Playgroud)
和存储库:
public interface PersonRepository extends JpaRepository<Person, Long> {
Stream<Person> findTop10ByFirstName(String firstName);
}
Run Code Online (Sandbox Code Playgroud)
我得到:
org.springframework.dao.InvalidDataAccessApiUsageException:您正在尝试在没有周围事务的情况下执行流查询方法,该事务保持连接打开,以便可以实际使用流。确保使用流的代码使用 @Transactional 或任何其他声明(只读)事务的方式。
我有一个类说UserService,它实现了Service并使用Service StereoType进行了注释,我正在使用Spring AOP并希望为此做临时解决方法(我知道这可以用更好的方式完成)
@Service
public class UserService implements Service{
@Autowired
private Service self;
}
Run Code Online (Sandbox Code Playgroud)
我试过这个但是得到了BeanNotFoundException,我错过了什么吗?
我知道我必须使用带有@Configurable的AspectJ,但只是寻找一些临时的解决方法
spring ×8
java ×6
spring-aop ×2
aop ×1
aspectj ×1
caching ×1
ehcache ×1
hibernate ×1
java-8 ×1
rollback ×1
spring-async ×1
transactions ×1