트랜잭션 (Transactions)

Isar 에서 트랜잭션은 단일 작업 단위 안에서 여러 데이터베이스 작업들을 합치게 됩니다. Isar 와의 대부분의 상호작용은 암묵적으로 트랜잭션을 사용합니다. Isar 의 읽기 및 쓰기 접근은 ACIDopen in new window 를 준수합니다. 오류가 발생하면 트랜잭션은 자동으로 롤백됩니다.

명시적 트랜잭션

명시적 트랜잭션에서는 데이터베이스의 일관된 스냅샷을 얻을 수 있습니다. 트랜잭션 시간을 최소화하려고 노력하세요. 트랜잭션 내부에서 네트워크 호출 및 기타 장기적인 작업들은 금지됩니다.

트랜잭션 (특히 쓰기 트랜잭션) 은 비용이 많이 들기 때문에 항상 연속적인 작업들을 단일 트랜잭션으로 그룹화해야 합니다.

트랜잭션은 동기식이나 비동기식일 수 있습니다. 동기적인 트랜잭션에서는 동기 연산만 수행할 수 있습니다. 비동기식 트랜잭션에서는 비동기 연산만 수행할 수 있습니다.

읽기읽기 & 쓰기
동기.read().write()
비동기.readAsync().writeAsync()

읽기 트랜잭션

명시적 읽기 트랜잭션은 선택 사항이지만, 원자적 읽기(atomic reads) 를 수행하고 트랜잭션 내부의 데이터베이스의 일관된 상태에 의존할 수 있게 해줍니다. 내부적으로 Isar 는 모든 읽기 작업에 항상 암시적 읽기 트랜잭션을 사용합니다.

비동기 읽기 트랜잭션은 다른 읽기 및 쓰기 트랜잭션과 병렬로 실행됩니다. 꽤 멋있지 않나요?

쓰기 트랜잭션

읽기 연산과 달리, Isar 에서 쓰기 연산은 반드시 명시적 트랜잭션으로 감싸야 합니다.

쓰기 트랜잭션이 성공적으로 완료되면 자동으로 커밋되고 모든 변경사항이 디스크에 기록됩니다. 오류가 발생하면 트랜잭션이 중단되고 모든 변경 사항이 롤백됩니다. 트랜잭션은 "전부가 아니면 아무것도 없다(all or nothing)" 입니다. 트랜잭션 내의 모든 쓰기가 성공하거나, 아니면 데이터 일관성을 보장하기 위해서 모두 무효가 되거나 입니다.

경고

데이터베이스 연산이 실패하면, 그 트랜잭션은 중단되므로 더 이상 사용할 수 없습니다. 다트에서 그 오류를 캐치(catch) 하더라도요.

@collection
class Contact {
  late int id;

  String? name;
}

// GOOD
await isar.writeAsync((isar) async {
  for (var contact in getContacts()) {
    await isar.contacts.put(contact);
  }
});

// BAD: 트랜잭션 안으로 for 루프를 이동시키세요.
for (var contact in getContacts()) {
  await isar.writeAsync((isar) async {
    await isar.contacts.put(contact);
  });
}