我正在尝试更新异步线程内的资源,该资源重复其任务直到被取消。我使用Future将线程存储在一个hashmap中,以便以后可以取消它。线程按预期分叉,并且Async方法中的对象实例更改其值,但是当我尝试提交它们时,更改不会反映在数据库中,我在控制台上看不到任何错误消息。我已经尝试过@Async和@Transactional的许多不同组合,但仍然没有得到它。我究竟做错了什么?在此先感谢您的帮助!
RoomService.java
@Service
@Transactional
public class RoomService {
@Inject private FooService fooService;
...
public Future<String> startRoom(Room room) {
Future<String> future = fooService.startFoo(room.getId());
map.put(room.getId(), future);
return future;
}
FooService.java
@Service
@Transactional
public class FooService {
...
public void save(Foo foo) {
getSession().saveOrUpdate(foo);
}
@Async
public Future<String> startFoo(int id) {
Foo foo = getFooById(id);
try {
while (true) {
foo.setName("Peter");
save(foo);
Thread.sleep(10000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return new AsyncResult<String>("done");
}
答案 0 :(得分:1)
让@Async
方法成为@Transactional
bean的一部分意味着Spring会截获您的方法两次:一次用于@Transactional
将方法包装在Transaction
中,一次用于{ {1}}在单独的@Async
中执行该方法。
由于proxying works的方式,一旦你进入Thread
的方法,就会调用
另一种方法是在实际对象上完成,而不是在具有所有FooService
行为的代理上完成。因此,不会创建/提交/回滚新事务。实际的@Transactional
边界是Transaction
方法本身。但是,由于您的方法执行无限循环,因此该提交永远不会发生。
我建议您在另一个类中创建@Async
方法,并为其创建一个bean并注入@Async
。这样,FooService
行为将实际调用包装到
@Transactional
因此在每次调用时都会提交。