# SpreadJS 동시 편집 정책

## Content

이 매뉴얼은 SpreadJS 동시 작업에서의 동작 방식과 사용 정책을 설명합니다. 이러한 메커니즘은 공유 통합 문서 환경에서 여러 클라이언트 간 실시간 동기화가 어떻게 이루어지는지를 제어합니다.

### 목적

* 개발자가 변경 사항이 언제, 어떻게 클라이언트 간에 동기화되는지 이해하도록 보장
* 스타일, 인쇄 설정 또는 기타 중첩 객체를 수정하는 올바른 방법 정의
* 수식 계산, 동기화 및 반복 계산 중 동작을 제어하는 규칙 설명

## 기능 설명

### 1\. 중첩 객체 수정 동기화

#### 핵심 개념

* **중첩 객체에 대한 직접적인 로컬 수정은 클라이언트 간에 동기화되지 않습니다.**
* 업데이트를 동기화하려면 setter 메서드를 통해 객체 전체를 **재설정 또는 재할당**해야 합니다.

#### 예시 사례

| 시나리오 | 로컬 영향 | 동기화 동작 | 권장 방식 |
| ---- | ----- | ------ | ----- |
| `getStyle(row, column)`에서 반환된 객체의 속성 수정 | 해당 클라이언트에서만 스타일 변경 표시 | 변경 내용은 다른 클라이언트로 **전파되지 않음** | `setStyle(row, column, style)`을 사용해 객체 전체 교체 |
| `printInfo`의 중첩 속성 수정 (예: `printInfo.pageHeaderFooter.left()`) | 로컬 뷰에만 영향 | 동기화되지 않음 | 전체 setter를 사용해 인쇄 설정 재할당 (예: `sheet.printInfo = new PrintInfo()`) |

#### 동기화 전략

정상적인 동기화를 트리거하려면 다음 절차를 따르십시오.

1. 수정하려는 객체를 가져옵니다.
2. 로컬에서 객체를 수정합니다.
3. **setter**를 호출하여 수정된 전체 객체를 워크시트 또는 통합 문서에 다시 적용합니다.

**예제:**

```auto
// 잘못된 방법 – 동기화되지 않음
let s = sheet.getStyle(1, 1);
s.backColor = "yellow"; // 로컬에만 적용

// 올바른 방법 – 동기화됨
let style = sheet.getStyle(1, 1);
style.backColor = "yellow";
sheet.setStyle(1, 1, style); // 동시 작업 동기화 트리거
```

***

### 2\. 수식 동시 작업 동작

동시 작업 환경에서 수식은 다르게 동작합니다. 각 클라이언트는 공유된 수식 정의를 기반으로 독립적으로 계산을 수행하며, 자체적인 로컬 상태를 유지합니다.

#### 스냅샷 저장

* 스냅샷에는 **수식 표현식**만 저장됩니다.
* **수식 결과 값**은 저장되거나 클라이언트 간에 동기화되지 않습니다.

#### 수식 재계산

* 통합 문서가 로드될 때 각 클라이언트는 수식을 독립적으로 재계산합니다.
* 실행 순서나 반복 계산 차이로 인해 재계산 결과가 일시적으로 다를 수 있습니다.

#### 동기화 범위

* 동시 작업 서비스는 수식 편집 작업(삽입, 삭제, 수정)을 동기화합니다.
* 계산 결과(숫자 출력 값)는 전송되거나 동기화되지 않습니다.

#### CalculationMode 정책

* 각 클라이언트는 자체적인 `CalculationMode`(수동 또는 자동)를 유지합니다.
* 한 클라이언트의 계산 모드 변경은 다른 클라이언트나 서버에 **영향을 주지 않습니다.**

다음 원칙을 따르십시오.

1. 일반적인 방식으로 수식을 작성합니다 (예: `=A1 + B1`).
2. 저장된 결과 값에 의존하지 마십시오 — 각 클라이언트는 독립적으로 재계산합니다.
3. 반복 계산 또는 휘발성 함수(`RAND`, `NOW` 등)를 사용할 때는 주의하십시오. 클라이언트마다 결과가 달라질 수 있습니다.

#### 반복 계산 동작

| 구분 | 설명 | 수식 예시 | 동기화 동작 |
| --- | --- | ----- | ------ |
| **자기 수렴(Self-Converging)** | 안정된 결과에 도달할 때까지 반복 (모든 클라이언트에서 동일) | 부서 간 비용 배분 상호 참조 | 클라이언트 및 새로 고침 간 일관성 유지 |
| **비수렴(Non-Converging)** | 무한 또는 불안정하게 반복 | `=A1 + 1` | 클라이언트마다 다름, 새로 고침 후 초기화 |
| **자동 데이터 입력(1회성)** | 한 번만 반복 실행 (예: 타임스탬프) | `=IF(A1="","", IF(B1="", NOW(), B1))` | 클라이언트별 독립 타임스탬프, 새로 고침 후 초기화 |

***

### 3\. 통합 문서 동시 작업 상태

사용자가 **[workbook.collaboration.onChangeSet](/spreadjs/api/v19/classes/GC.Spread.Sheets.Collaboration.Collaboration#onchangeset)**을 통해 변경 집합 리스너를 등록하면, SpreadJS는 동시 작업 상태로 간주됩니다.
SpreadJS가 동시 작업 모드에 있을 때는 동시 작업의 데이터 동기화 메커니즘으로 인해 일부 API가 무효화되어(동작하지 않음) 사용 효과가 없습니다.

| `API 위치` | `API 이름` |
| ------ | ------ |
| `Workbook` | `fromJSON` |
| `Workbook` | `import` |
| `Workbook` | `open` |
| `Worksheet` | `reset` |
