Files
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.

Follows the import procedure in README.md.

  source/     the originating repository verbatim — 78 documents, 28 SVGs,
              8 manifests, plus .source-revision recording the commit
  final/      the SSOT
    document.md   729 lines written from the 29 experiment documents, not
                  concatenated: what was predicted, what was measured, and
                  where the measurement itself was wrong
    evidence/raw    125 outputs, flattened to <experiment>__<file> because
                    the originals collided (01-baseline.txt appeared three
                    times) and the audit only globs the top level
    evidence/meta   one per raw file; command and exitCode are null and the
                    README says why rather than inventing them
    evidence/browser  22 captures
    assets/       three diagrams through techviz
    .techviz/     their VizSpecs

A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.

Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.

verify-pipeline.py passes. audit-records.py reports no issues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:51:59 +09:00

138 lines
26 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="2724" viewBox="0 0 1200 2724" role="img">
<title>terminal evidence</title>
<desc>Terminal-style rendering generated from retained command output. Sensitive-looking values are redacted in the visual asset.</desc>
<rect x="1" y="1" width="1198" height="2722" rx="14" fill="#0d1117" stroke="#30363d"/>
<rect x="1" y="1" width="1198" height="44" rx="14" fill="#161b22"/>
<rect x="1" y="30" width="1198" height="14" fill="#161b22"/>
<circle cx="24" cy="22" r="6" fill="#ff5f57"/>
<circle cx="44" cy="22" r="6" fill="#febc2e"/>
<circle cx="64" cy="22" r="6" fill="#28c840"/>
<text x="92" y="27" fill="#8b949e" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">terminal evidence</text>
<text x="24" y="68" fill="#c9d1d9" font-size="15" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">$ set -e
J=src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/transaction
B=</tspan><tspan x="24" dy="22">src/app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/jpa
echo &quot;# 삭제를 설명하는 문단과 그 마지막 문장</tspan><tspan x="24" dy="22">&quot;
sed -n &quot;33,39p&quot; $B/JpaTransactionAutoConfiguration.java
echo
echo &quot;# 그 문장이 지목한 클래스의 선언&quot;
grep -n &quot;public f</tspan><tspan x="24" dy="22">inal class FullTransactionRetryCoordinator&quot; $J/FullTransactionRetryCoordinator.java | sed &quot;s/^/ /&quot;
echo
echo &quot;# 그 포</tspan><tspan x="24" dy="22">트를 실제로 구현하는 클래스&quot;
grep -rn &quot;implements PolicyTransactionPort&quot; --include=*.java src | grep &quot;/src/main/&quot; | sed </tspan><tspan x="24" dy="22">&quot;s|.*/java/dev/caskeleton/| |&quot;
grep -n &quot;@Component&quot; $J/SpringTransactionPort.java | sed &quot;s/^/ /&quot;
echo
echo &quot;# 조립</tspan><tspan x="24" dy="22">된 쪽의 재시도 루프와 그 게이트&quot;
sed -n &quot;63,73p&quot; $J/SpringPolicyTransactionPort.java
sed -n &quot;143,149p&quot; $J/SpringPolicyTr</tspan><tspan x="24" dy="22">ansactionPort.java
echo
echo &quot;# 두 구현이 읽는 값&quot;
sed -n &quot;38,43p&quot; $J/JpaTransactionSettings.java
grep -n &quot;DEFAULT_MAX_R</tspan><tspan x="24" dy="22">ETRY_ELAPSED\|retryCoordinator(&quot; $B/JpaTransactionAutoConfiguration.java | sed &quot;s/^/ /&quot;
echo
echo &quot;# main 에서 코디네</tspan><tspan x="24" dy="22">이터를 언급하는 파일 전부&quot;
grep -rn &quot;FullTransactionRetryCoordinator&quot; --include=*.java src | grep &quot;/src/main/&quot; | sed &quot;s|</tspan><tspan x="24" dy="22">.*/java/dev/caskeleton/| |&quot;
echo
echo &quot;# 파라미터로 받거나 컨테이너에서 꺼내는 곳&quot;
printf &quot; FullTransactionRetryCo</tspan><tspan x="24" dy="22">ordinator 를 파라미터로 받는 선언 : %s\n&quot; &quot;$(grep -rn &#x27;FullTransactionRetryCoordinator [a-z]&#x27; --include=*.java src | gre</tspan><tspan x="24" dy="22">p &#x27;/src/main/&#x27; | grep -v &#x27;public FullTransactionRetryCoordinator&#x27; | wc -l)&quot;
printf &quot; ObjectProvider&lt;FullTransactionRe</tspan><tspan x="24" dy="22">tryCoordinator&gt; : %s\n&quot; &quot;$(grep -rn &#x27;ObjectProvider&lt;FullTransactionRetryCoordinator&gt;&#x27; --include=*.java src | wc -l)&quot;
pri</tspan><tspan x="24" dy="22">ntf &quot; getBean 으로 이 타입을 꺼내는 곳 : %s\n&quot; &quot;$(grep -rn &#x27;getBean(FullTransactionRetryCoordinator&#x27; --include=*.java</tspan><tspan x="24" dy="22"> src | wc -l)&quot;
printf &quot; 소스 밖에서 이 이름이 나오는 곳 : %s\n&quot; &quot;$(grep -rn &#x27;FullTransactionRetryCoordinator&#x27; src --b</tspan><tspan x="24" dy="22">inary-files=without-match --exclude-dir=build --exclude-dir=.gradle 2&gt;/dev/null | grep -vc &#x27;\.java:&#x27; || true)&quot;
echo
echo</tspan><tspan x="24" dy="22"> &quot;# 선언된 능력&quot;
grep -n &quot;Full-transaction retry&quot; docs/jpa/support-matrix.md | sed &quot;s/^/ /&quot;
echo
echo &quot;# 지워진 이름</tspan><tspan x="24" dy="22">을 건드린 커밋 (경로 제한 없음)&quot;
git log --all --oneline -S&quot;RetryableJpaTransactionInterceptor&quot; | sed &quot;s/^/ /&quot;
echo
e</tspan><tspan x="24" dy="22">cho &quot;# 같은 트리에서 이미 도는 AOP&quot;
grep -rn &quot;@Transactional&quot; --include=*.java src/adapter/outbound/persistence-jpa/src/</tspan><tspan x="24" dy="22">main | sed &quot;s|.*/java/dev/caskeleton/| |&quot; | head -4
grep -n &quot;Advisor\|AnnotationMatchingPointcut&quot; src/adapter/inbound</tspan><tspan x="24" dy="22">/web/src/main/java/dev/caskeleton/adapter/inbound/web/authz/MethodSecurityConfig.java | sed &quot;s/^/ /&quot; | head -4</tspan></text>
<text x="24" y="552" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">cwd: /shared/codebase/clean-architecture-backend-template</tspan></text>
<text x="24" y="574" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">time: 2026-09-02T13:33:03+00:00 · exit 0</tspan></text>
<line x1="24" y1="588" x2="1176" y2="588" stroke="#30363d"/>
<text x="24" y="628" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 삭제를 설명하는 문단과 그 마지막 문장</tspan></text>
<text x="24" y="650" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> * &lt;p&gt;There is no declarative retry annotation any more. {@code @RetryableJpaTransaction} lived in</tspan></text>
<text x="24" y="672" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> * the persistence leaf and documented itself as something an application service would put on its</tspan></text>
<text x="24" y="694" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> * own methods — which application-core cannot do without importing an outbound adapter and</tspan></text>
<text x="24" y="716" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> * inverting the dependency this architecture is built on. The canonical boundary is {@code</tspan></text>
<text x="24" y="738" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> * PolicyTransactionPort.inTransaction(TransactionRequest, Supplier)}; the retry coordinator below</tspan></text>
<text x="24" y="760" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> * is what implements it, not a second way to ask for the same thing.</tspan></text>
<text x="24" y="782" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> */</tspan></text>
<text x="24" y="804" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="826" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 문장이 지목한 클래스의 선언</tspan></text>
<text x="24" y="848" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 30:public final class FullTransactionRetryCoordinator {</tspan></text>
<text x="24" y="870" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="892" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 포트를 실제로 구현하는 클래스</tspan></text>
<text x="24" y="914" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence/transaction/SpringTransactionPort.java:31:public class SpringTransactionPort implements PolicyT</tspan><tspan x="24" dy="22">ransactionPort {</tspan></text>
<text x="24" y="958" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 30:@Component</tspan></text>
<text x="24" y="980" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1002" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 조립된 쪽의 재시도 루프와 그 게이트</tspan></text>
<text x="24" y="1024" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> int attempt = 1;</tspan></text>
<text x="24" y="1046" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> while (true) {</tspan></text>
<text x="24" y="1068" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> AttemptResult&lt;T&gt; attemptResult = executeOnce(request, action, policy);</tspan></text>
<text x="24" y="1090" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> if (!shouldRetry(request.policyId(), attemptResult, attempt)) {</tspan></text>
<text x="24" y="1112" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> return attemptResult.result();</tspan></text>
<text x="24" y="1134" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> }</tspan></text>
<text x="24" y="1156" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> if (!retryBackoff.pauseBeforeRetry(request.callBudget(), attempt)) {</tspan></text>
<text x="24" y="1178" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> return attemptResult.result();</tspan></text>
<text x="24" y="1200" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> }</tspan></text>
<text x="24" y="1222" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> attempt++;</tspan></text>
<text x="24" y="1244" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> }</tspan></text>
<text x="24" y="1266" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> private boolean shouldRetry(</tspan></text>
<text x="24" y="1288" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> TransactionPolicyId policyId, AttemptResult&lt;?&gt; attemptResult, int attempt) {</tspan></text>
<text x="24" y="1310" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> if (policyId != TransactionPolicyId.COMMAND_SERIALIZABLE_REPLAY_SAFE</tspan></text>
<text x="24" y="1332" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> || !attemptResult.physicalOwner()</tspan></text>
<text x="24" y="1354" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> || attempt &gt;= retryBackoff.maximumAttempts()</tspan></text>
<text x="24" y="1376" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> || Thread.currentThread().isInterrupted()) {</tspan></text>
<text x="24" y="1398" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> return false;</tspan></text>
<text x="24" y="1420" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1442" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 두 구현이 읽는 값</tspan></text>
<text x="24" y="1464" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> transactionMargin = defaulted(transactionMargin, Duration.ofMillis(250), &quot;transaction-margin&quot;);</tspan></text>
<text x="24" y="1486" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> lockMargin = defaulted(lockMargin, Duration.ofMillis(100), &quot;lock-margin&quot;);</tspan></text>
<text x="24" y="1508" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> retryBaseDelay = defaulted(retryBaseDelay, Duration.ofMillis(10), &quot;retry-base-delay&quot;);</tspan></text>
<text x="24" y="1530" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> retryMaximumDelay = defaulted(retryMaximumDelay, Duration.ofMillis(50), &quot;retry-maximum-delay&quot;);</tspan></text>
<text x="24" y="1552" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> retryMaximumAttempts = retryMaximumAttempts == null ? 2 : retryMaximumAttempts;</tspan></text>
<text x="24" y="1574" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1596" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 43: public static final Duration DEFAULT_MAX_RETRY_ELAPSED = Duration.ofSeconds(30);</tspan></text>
<text x="24" y="1618" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 99: public FullTransactionRetryCoordinator retryCoordinator(</tspan></text>
<text x="24" y="1640" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 103: return retryCoordinator(executor, DefaultJpaRetryPolicy.forProfile(retryProfile), listener);</tspan></text>
<text x="24" y="1662" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 107: public FullTransactionRetryCoordinator retryCoordinator(</tspan></text>
<text x="24" y="1684" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 110: executor, policy, retrySleeper(), clock, DEFAULT_MAX_RETRY_ELAPSED, listener);</tspan></text>
<text x="24" y="1706" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1728" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># main 에서 코디네이터를 언급하는 파일 전부</tspan></text>
<text x="24" y="1750" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> bootstrap/autoconfigure/jpa/JpaPlatformRuntimeAutoConfiguration.java:7:import dev.caskeleton.adapter.outbound.persistence.tr</tspan><tspan x="24" dy="22">ansaction.FullTransactionRetryCoordinator;</tspan></text>
<text x="24" y="1794" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> bootstrap/autoconfigure/jpa/JpaPlatformRuntimeAutoConfiguration.java:170: public FullTransactionRetryCoordinator jpaRetryCo</tspan><tspan x="24" dy="22">ordinator(</tspan></text>
<text x="24" y="1838" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> bootstrap/autoconfigure/jpa/JpaTransactionAutoConfiguration.java:9:import dev.caskeleton.adapter.outbound.persistence.transa</tspan><tspan x="24" dy="22">ction.FullTransactionRetryCoordinator;</tspan></text>
<text x="24" y="1882" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> bootstrap/autoconfigure/jpa/JpaTransactionAutoConfiguration.java:99: public FullTransactionRetryCoordinator retryCoordinato</tspan><tspan x="24" dy="22">r(</tspan></text>
<text x="24" y="1926" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> bootstrap/autoconfigure/jpa/JpaTransactionAutoConfiguration.java:107: public FullTransactionRetryCoordinator retryCoordinat</tspan><tspan x="24" dy="22">or(</tspan></text>
<text x="24" y="1970" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> bootstrap/autoconfigure/jpa/JpaTransactionAutoConfiguration.java:109: return new FullTransactionRetryCoordinator(</tspan></text>
<text x="24" y="1992" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence/transaction/FullTransactionRetryCoordinator.java:30:public final class FullTransactionRetryCoor</tspan><tspan x="24" dy="22">dinator {</tspan></text>
<text x="24" y="2036" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence/transaction/FullTransactionRetryCoordinator.java:50: public FullTransactionRetryCoordinator(</tspan></text>
<text x="24" y="2058" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence/transaction/SpringJpaTransactionExecutor.java:21: * &lt;p&gt;This class does not retry. Retry lives i</tspan><tspan x="24" dy="22">n {@link FullTransactionRetryCoordinator}, which calls</tspan></text>
<text x="24" y="2102" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2124" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 파라미터로 받거나 컨테이너에서 꺼내는 곳</tspan></text>
<text x="24" y="2146" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> FullTransactionRetryCoordinator 를 파라미터로 받는 선언 : 0</tspan></text>
<text x="24" y="2168" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> ObjectProvider&lt;FullTransactionRetryCoordinator&gt; : 0</tspan></text>
<text x="24" y="2190" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> getBean 으로 이 타입을 꺼내는 곳 : 0</tspan></text>
<text x="24" y="2212" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 소스 밖에서 이 이름이 나오는 곳 : 0</tspan></text>
<text x="24" y="2234" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2256" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 선언된 능력</tspan></text>
<text x="24" y="2278" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 83:| Full-transaction retry | Stable |</tspan></text>
<text x="24" y="2300" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2322" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 지워진 이름을 건드린 커밋 (경로 제한 없음)</tspan></text>
<text x="24" y="2344" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> e98b56eb feat: jpa, messaging, notification, mongo, graphql 어댑터터 리펙토링</tspan></text>
<text x="24" y="2366" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 2f5d2fc2 feat: jpa, messaging, notification, mongo, graphql 어댑터터 구현체 추가</tspan></text>
<text x="24" y="2388" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 0e61f86e feat(jpa): implement the JPA relational persistence platform</tspan></text>
<text x="24" y="2410" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 3b5aee50 feat: 설계 문서 추가</tspan></text>
<text x="24" y="2432" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2454" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 같은 트리에서 이미 도는 AOP</tspan></text>
<text x="24" y="2476" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence/fileserver/JpaFileMetadataStore.java:34: * {@code @Transactional} of their own.</tspan></text>
<text x="24" y="2498" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence/outbox/OutboxReaper.java:38: @Transactional</tspan></text>
<text x="24" y="2520" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence/outbox/OutboxStoreAdapter.java:20: * {@code @Transactional} of their own; {@link #claimBatch} d</tspan><tspan x="24" dy="22">elegates the vendor claim to {@link</tspan></text>
<text x="24" y="2564" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence/outbox/OutboxStoreAdapter.java:21: * OutboxClaimRepository}. See README &quot;outbox&quot; for the append</tspan><tspan x="24" dy="22">/claim/no-@Transactional contracts.</tspan></text>
<text x="24" y="2608" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 6:import org.springframework.aop.Advisor;</tspan></text>
<text x="24" y="2630" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 9:import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;</tspan></text>
<text x="24" y="2652" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 50: static Advisor requiresPermissionAuthorizationAdvisor(</tspan></text>
<text x="24" y="2674" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 55: Pointcut onMethod = AnnotationMatchingPointcut.forMethodAnnotation(RequiresPermission.class);</tspan></text>
</svg>