Untitled

수정 전 루틴 저장 Dao

suspend fun insertRoutine(
    routine: Routine,
    days: List<Day>,
    exercises: List<Exercise>,
    sets: List<ExerciseSet>
) {
    insertRoutineInfo(routine)
    insertDays(days)
    insertExercises(exercises)
    insertSets(sets)
}

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertRoutineInfo(routine: Routine)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertDays(days: List<Day>)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertExercises(exercises: List<Exercise>)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertSets(sets: List<ExerciseSet>)

위 코드는 수정 전 루틴 dao의 코드이다.

insertRoutine()에서 아래에 정의된 Insert 함수 4개를 호출하고 있다.

그리고 이 루틴 dao의 구현체를 살펴보자.

수정 전 루틴 저장 DaoImpl

@Override
public Object insertRoutineInfo(
    final Routine routine,
    final Continuation<? super Unit> continuation
) {
  return CoroutinesRoom.execute(__db, true, new Callable<Unit>() {
    @Override
    public Unit call() throws Exception {
      __db.beginTransaction();
      try {
        __insertionAdapterOfRoutine.insert(routine);
        __db.setTransactionSuccessful();
        return Unit.INSTANCE;
      } finally {
        __db.endTransaction();
      }
    }
  }, continuation);
}

@Override
public Object insertDays(
    final List<Day> days, 
    final Continuation<? super Unit> continuation
) {
    return CoroutinesRoom.execute(__db, true, new Callable<Unit>() {
      @Override
      public Unit call() throws Exception {
        __db.beginTransaction();
        try {
          __insertionAdapterOfDay.insert(days);
          __db.setTransactionSuccessful();
          return Unit.INSTANCE;
        } finally {
          __db.endTransaction();
        }
      }
    }, continuation);
  }

@Override
public Object insertExercises(
    final List<Exercise> exercises,
    final Continuation<? super Unit> continuation
) {
    return CoroutinesRoom.execute(__db, true, new Callable<Unit>() {
      @Override
      public Unit call() throws Exception {
        __db.beginTransaction();
        try {
          __insertionAdapterOfExercise.insert(exercises);
          __db.setTransactionSuccessful();
          return Unit.INSTANCE;
        } finally {
          __db.endTransaction();
        }
      }
    }, continuation);
  }

@Override
public Object insertSets(
    final List<ExerciseSet> sets,
    final Continuation<? super Unit> continuation
) {
    return CoroutinesRoom.execute(__db, true, new Callable<Unit>() {
      @Override
      public Unit call() throws Exception {
        __db.beginTransaction();
        try {
          __insertionAdapterOfExerciseSet.insert(sets);
          __db.setTransactionSuccessful();
          return Unit.INSTANCE;
        } finally {
          __db.endTransaction();
        }
      }
    }, continuation);
  }

@Override
public Object insertRoutine(
    final Routine routine, 
    final List<Day> days,
    final List<Exercise> exercises, 
    final List<ExerciseSet> sets,
    final Continuation<? super Unit> continuation
) {
  return RoutineDao.DefaultImpls.insertRoutine(
    RoutineDao_Impl.this, 
    routine, 
    days, 
    exercises, 
    sets, 
    continuation
  );
}

각각의 Insert 함수마다 별도로 트랜잭션을 수행하고 있다.

따라서 하나의 Insert 함수가 실패해도 그전에 저장된 데이터는 남아있게 된다.

하지만 루틴 데이터는 관련 데이터가 전부 저장되어야 할 필요가 있으므로 전체 Insert 작업을 하나의 트랜잭션으로 수행해야 한다.

@Transaction
suspend fun insertRoutine(
    routine: Routine,
    days: List<Day>,
    exercises: List<Exercise>,
    sets: List<ExerciseSet>
) {
    insertRoutineInfo(routine)
    insertDays(days)
    insertExercises(exercises)
    insertSets(sets)
}

따라서 루틴 dao의 insertRoutine()@Transaction을 추가하고 dao의 구현체를 확인해보았다.