【发布时间】:2017-06-07 04:15:07
【问题描述】:
我有一个关于@Transactional 注释的问题。 没有什么特别的定义,据我所知是 PROPAGATION_REQUIRED 假设我在服务层和 dao 层都有一个事务注释。
服务
@Transactional
public long createStudentInDB(Student student) {
final long id = addStudentToDB (student);
addStudentToCourses (id, student.getCourseIds());
return id;
}
private long addStudentToDB (Student student) {
StudentEntity entity = new StudentEntity ();
convertToEntity(student, entity);
try {
final id = dao.create(entity);
} catch (Exception e){
//
}
return id;
}
private void addStudentToCourses (long studentId, List<String> coursesIds){
//add user to group
if(coursesIds!= null){
List<StudentCourseEntity> studentCourses = new ArrayList<>();
for(String coursesId: coursesIds){
StudentCourseEntity entity = new StudentCourseEntity ();
entity.setCourseId(coursesId);
entity.setStudentId(userId);
studentCourses.add(studentId);
}
anotherDao.saveAll(studentCourses);
}
}
道
@Transactional
public UUID create(StudentEntity entity) {
if ( entity == null ) { throw new Exception(//…); }
getCurrentSession().save(entity);
return entity.getId();
}
另一个 DAO:
@Transactional
public void saveAll(Collection< StudentCourseEntity > studentCourses) {
List< StudentCourseEntity > result = new ArrayList<>();
if(studentCourses!= null) {
for (StudentCourseEntity studentCourse : studentCourses) {
if (studentCourse!= null) {
save(studentCourse);
}
}
}
}
尽管这不是最优的,但它似乎会导致死锁。 假设我最多有 2 个到数据库的连接。 我正在使用 3 个不同的线程来运行相同的代码。 线程 1 和线程 2 收到连接,线程 3 没有获得任何连接。 不仅如此,似乎线程 1 在尝试获取 dao 级别的连接时卡住了,线程 2 也是如此。导致死锁。
我确信通过使用propagation_required 这不会发生。 我错过了什么吗? 对这样的事情有什么建议?有没有办法可以在两层都有@transactional?如果不是,哪个是首选? 谢谢 法布里奇奥
【问题讨论】:
-
如果你的连接用完了,你要么没有正确设置事务,要么自己搞乱了连接,而不是让 Spring 管理事情。仅添加没有实现的方法签名将无助于解决您的问题。首先检查您的设置(确保您的 tx 设置正确)并检查您的实现。