@Transactional
当@Transactional
注解写在函数上之后,就表示这个函数开启了事务。事务是基于数据库连接的connect。
parallelStream
这是针对List
进行多线程Stream
的操作。
//对list集合开启多线程操作
list.parallelStream().forEach(item->{
//业务代码
})
@Transactional 和 parallelStream结合使用
@Transactional
public void batchUpdate(List list){
list.parallelStream().forEach(item->{
service.update(item);
})
}
上面的代码表示在一个开启事务的函数中使用多线程并发更新数据。这个时候会出现一个问题,由于事务是基于数据库连接的,如果在函数中使用多线程对数据库进行操作,实际上每一个线程都对应一个数据库连接,且这些子连接并没有开启事务,也不会收到主线程中事务的约束。如果在某一个子线程中出现了错误,事务是不会发生回滚的。
解决这个问题就是检查一下代码:
- 如果在使用了
parallelStream
的函数中,没有使用@Transactional
直接开启事务,那么业务不会受到影响。 - 如果在开启了事务的情况下,没有在
parallelStream
中进行更新/新增操作,也不会出现事务的问题。 - 在数据量大的情况下,可以使用
parallelStream
在多线程中并发处理数据,接着在主线程中对数据进行新增/修改