在Java中使用线程时获得两个打开的会话
我正在使用线程在hibernate数据库中并行存储一些数据。我需要这样做,因为在将信息保存到数据库之前,我需要运行一些需要几分钟的任务。所以我实现了线程 所以,我必须创建同一个类的实例,比如学生,每个学生都有一个我随机生成的唯一代码(不是ID),为了确保它是唯一的,在保存该学生之前,我检查没有其他学生使用该代码 问题是,当我想检查第二个学生的代码是否唯一(第一个正确存储)时,我得到 当我做选择的时候。。。 我使用Autowired类来建立其他类(服务、Dao等)的关联,并为线程运行 下面是一些代码: StudentServiceImpl:在Java中使用线程时获得两个打开的会话,java,multithreading,hibernate,autowired,Java,Multithreading,Hibernate,Autowired,我正在使用线程在hibernate数据库中并行存储一些数据。我需要这样做,因为在将信息保存到数据库之前,我需要运行一些需要几分钟的任务。所以我实现了线程 所以,我必须创建同一个类的实例,比如学生,每个学生都有一个我随机生成的唯一代码(不是ID),为了确保它是唯一的,在保存该学生之前,我检查没有其他学生使用该代码 问题是,当我想检查第二个学生的代码是否唯一(第一个正确存储)时,我得到 当我做选择的时候。。。 我使用Autowired类来建立其他类(服务、Dao等)的关联,并为线程运行 下面是一些代
@Autowired
RunSomeTaskService runSomeTaskService;
@Override
Transactional
public Response save(StudentBO[] students, String username) throws Exception {
...
for (StudentBO student : students) {
Student s = new Student();
String code = UUID.randomUUID().toString();
while(this.studentDao.getByCode(code) != null)
code = UUID.randomUUID().toString();
s.setCode(code);
....
this.studentDao.save(s);
runSomeTaskService.setData(s);
Thread t = new Thread(runSomeTaskService);
t.start();
}
public class RunSomeTaskServiceImpl extends CommonService implements RunSomeTaskService{
Response response;
Student student;
@Override
public void setData(Student student) {
this.response = new Response();
this.student = student;
}
}
@Override
public Response getResponse() {
return this.response;
}
@Override
@Transactional
public void run() {
//do some process that takes minutes
this.studentDao.add(this.student);
this.response = response;
}
RunSomeTaskService:
public interface RunSomeTaskService extends Runnable{
void setData(Student student);
Response getResponse();
}
RunSomeTaskServiceImpl:
@Autowired
RunSomeTaskService runSomeTaskService;
@Override
Transactional
public Response save(StudentBO[] students, String username) throws Exception {
...
for (StudentBO student : students) {
Student s = new Student();
String code = UUID.randomUUID().toString();
while(this.studentDao.getByCode(code) != null)
code = UUID.randomUUID().toString();
s.setCode(code);
....
this.studentDao.save(s);
runSomeTaskService.setData(s);
Thread t = new Thread(runSomeTaskService);
t.start();
}
public class RunSomeTaskServiceImpl extends CommonService implements RunSomeTaskService{
Response response;
Student student;
@Override
public void setData(Student student) {
this.response = new Response();
this.student = student;
}
}
@Override
public Response getResponse() {
return this.response;
}
@Override
@Transactional
public void run() {
//do some process that takes minutes
this.studentDao.add(this.student);
this.response = response;
}
StudentDaoImpl:
@Override
public Object addOrUpdate(Object item) throws Exception {
sessionFactory.getCurrentSession().saveOrUpdate(item);
return item;
}
@Override
public Object getByCode(String code) throws Exception {
Query q = sessionFactory.getCurrentSession().createQuery("FROM Student as e WHERE e.code = '" + code + "'");
return q.uniqueResult();
}
因此,我的问题是:
1-可以使用Autowired实例化RunSomeTaskService吗?我需要这个,因为如果我使用newrunsometaskservice()
,那么在dao层中sessionFactory是空的。但也许这样做是不对的,因为我只对所有学生使用了一个实例
2-为了避免代理出现两个打开会话的错误,我无法查阅(StudentBO student:students)的中的student表。这可以吗,还是问题有所不同
顺便说一句,这是我第一次使用线程。我让它工作
我将student对象保存在foreach中,然后用该对象启动一个新线程
解决方案是首先运行一个foreach来存储所有学生,然后运行另一个foreach来启动发送已存储对象的不同线程。不要将数据状态设置为RunSomeTaskServiceImpl,因为spring的默认配置允许对象作为单例。我建议在您的应用程序中使用@Asyncservice@WilderValera使用Async,我可以定义对于相同的情况,我需要等待响应,但是对于其他情况,我不想等待响应吗?您可以使用@Async de return a Future,然后根据您的情况,您可以使用get方法(这将阻止线程)返回值。看看这篇文章@WilderValera我实现了异步,但它不起作用。如果你能帮助我,那就太好了。