/** 트랜잭션 처리가 필요한 로직이 지정된 시간내에 완료되지 못하면 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");
   }
 }
 /** 정해진 시간안에 호출이 완료되지 않으 timeout 에러가 나야 한다. */
 @Test(expected = ExecuteTimeoutException.class)
 public void shouldThrowExecuteTimeoutException() {
   ExecuteFunction<String, String> func =
       new ExecuteFunction<String, String>() {
         public String apply(String t) {
           try {
             Thread.sleep(1000);
           } catch (Exception e) {
           }
           return t;
         }
       };
   timeoutSvc.executeInTransaction(func, "hello", 100);
 }
 /** 정해진 시간에 호출이 완료되는 경우 timeout없이 올바른 리턴값을 줘야한다. */
 @Test
 public void shouldReturnValueWithoutTimeout() {
   ExecuteFunction<String, String> func =
       new ExecuteFunction<String, String>() {
         public String apply(String t) {
           try {
             Thread.sleep(100);
           } catch (Exception e) {
           }
           return t;
         }
       };
   String expected = "hello";
   ExecuteResult<String> result = timeoutSvc.executeInTransaction(func, expected, 1000);
   assertThat(result.getReturnObject()).isEqualTo(expected);
 }
  /** 지정된 시간 내에 처리가 완료되면 트랜잭션은 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");
  }