JPA Hibernate Spring Repository确保事务在保存时完成?

时间:2016-09-19 18:12:41

标签: spring hibernate jpa

我正在创建一个简单的春季应用程序,它应该在研讨会上预订座位。让我们说Booking类看起来像这样

@Entity
@Table(name = "bookings")
@IdClass(BookingId.class)
public class Booking{
    @Id
    private Long seminarId;

    @Id
    private String seatNo;

    // .. other fields like perticipant info

    // .. getter setters
}

当然是BookingId类:

public class BookingId implements Serializable{
    private static final long serialVersionUID = 1L;
    private Long seminarId;
    private String seatNo;

    // .. constructors, getters, setters
}

我有repository

@Repository
public interface BookingsRepository extends JpaRepository<Booking, BookingId>{
}
当预订请求到达时,在控制器中

我首先检查是否已经存在具有相同的seminer id和座位号的预订,如果它不存在我创建一个

@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<BaseCrudResponse> createNewBooking(@Valid @RequestBody NewBookingDao newBookingDao, BindingResult bindingResult){
    logger.debug("Request for a new booking");

    // .. some other stuffs     
    Booking newBooking = new Booking();
    newBooking.setSeminarId(newBookingDao.getSeminarId());
    newBooking.setSeatNumber(newBookingDao.getSeatNumber());
    // .. set other fields
    Booking existing = bookingsRepository.findOne(new BookingId(newBooking.getSeminarId(), newBooking.getSeatNumber());
    if (existing == null)
        bookingsRepository.save(newBooking);

        return new ResponseEntity<>(new BaseCrudResponse(0), HttpStatus.CREATED);
    }

    return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);


}

现在如果save的{​​{1}}方法没有完成提交事务而另一个请求已经超过存在检查会发生什么?可能有不正确的预订(最后一次提交将覆盖之前的提交)。这种情况可能会发生吗?存储库是否会确保它在另一次保存调用之前完成事务?

还有什么方法可以告诉Jpa抛出一些异常(对于IntegrityConstraintException,如果复合键(在本例中为seminerId和seatNumber)已经存在?现在在当前设置中它只是更新行。

1 个答案:

答案 0 :(得分:1)

您可以使用javax.persistence.LockModeType.PESSIMISTIC_WRITE,因此除了获得锁定的事务之外的其他事务无法更新实体。

如果您使用spring-data&gt; 1.6您可以使用@Lock注释存储库方法:

interface BookingsRepository extends Repository<Booking, Long> {

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Booking findOne(Long id);
}

当然,您需要处理控制器中可能出现的锁定异常。