/** 트랜잭션 처리가 필요한 로직이 지정된 시간내에 완료되지 못하면 rollback을 한다. */
 @Test(expected = EmptyResultDataAccessException.class)
 public void shouldRollbackWhenTimedOut() {
   ExecuteFunction<Employee, Integer> func =
       new ExecuteFunction<Employee, Integer>() {
         public Integer apply(Employee emp) {
           Integer result = empService.addNewEmployee(emp);
           try {
             Thread.sleep(1000);
           } catch (Exception e) {
           }
           return result;
         }
       };
   empService.deleteById("committedOutOfTime");
   Employee emp = new Employee();
   emp.setId("committedOutOfTime");
   emp.setName("committedOutOfTime");
   try {
     timeoutSvc.executeInTransaction(func, emp, 100);
     Assert.fail("ExecuteTimeoutException should be thrown");
   } catch (ExecuteTimeoutException e) {
     // because insert execution has been rollbacked
     // the following method should throw EmptyResultDataAccessException
     empService.findById("committedOutOfTime");
   }
 }
  /** 지정된 시간 내에 처리가 완료되면 트랜잭션은 commit이 되야 한다. */
  @Test
  public void shouldCommitWhenExecutedInTime() {
    ExecuteFunction<Employee, Integer> func =
        new ExecuteFunction<Employee, Integer>() {
          public Integer apply(Employee emp) {
            return empService.addNewEmployee(emp);
          }
        };
    empService.deleteById("committedInTime");
    Employee emp = new Employee();
    emp.setId("committedInTime");
    emp.setName("committedInTime");
    ExecuteResult<Integer> result =
        timeoutSvc.<Employee, Integer>executeInTransaction(func, emp, 1000);

    assertThat(result.getReturnObject()).isEqualTo(1);
    Employee actual = empService.findById("committedInTime");
    assertThat(actual).isNotNull();
    assertThat(actual.getId()).isEqualTo("committedInTime");
  }