[{"data":1,"prerenderedAt":1024},["ShallowReactive",2],{"docs-nav:fr":3,"docs:\u002Ffr\u002Fdocs\u002Fbusiness\u002Ftogether":189},[4],{"title":5,"path":6,"stem":7,"children":8,"page":52},"Fr","\u002Ffr","fr",[9],{"title":10,"path":11,"stem":12,"children":13},"Qu'est-ce que Fougere","\u002Ffr\u002Fdocs","fr\u002Fdocs\u002Findex",[14,15,19,23,27,31,53,78,123,148],{"title":10,"path":11,"stem":12},{"title":16,"path":17,"stem":18},"Démarrer","\u002Ffr\u002Fdocs\u002Fgetting-started","fr\u002Fdocs\u002F01.getting-started",{"title":20,"path":21,"stem":22},"Une app que vous avez déjà","\u002Ffr\u002Fdocs\u002Fexisting-app","fr\u002Fdocs\u002F02.existing-app",{"title":24,"path":25,"stem":26},"Apportez votre schéma","\u002Ffr\u002Fdocs\u002Fbring-your-schema","fr\u002Fdocs\u002F03.bring-your-schema",{"title":28,"path":29,"stem":30},"La CLI","\u002Ffr\u002Fdocs\u002Fcli","fr\u002Fdocs\u002F04.cli",{"title":32,"path":33,"stem":34,"children":35,"page":52},"Concepts","\u002Ffr\u002Fdocs\u002Fconcepts","fr\u002Fdocs\u002F2.concepts",[36,40,44,48],{"title":37,"path":38,"stem":39},"Philosophie","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fphilosophy","fr\u002Fdocs\u002F2.concepts\u002F1.philosophy",{"title":41,"path":42,"stem":43},"La Frond","\u002Ffr\u002Fdocs\u002Fconcepts\u002Ffrond","fr\u002Fdocs\u002F2.concepts\u002F2.frond",{"title":45,"path":46,"stem":47},"Le chemin le plus court","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fshortest-path","fr\u002Fdocs\u002F2.concepts\u002F3.shortest-path",{"title":49,"path":50,"stem":51},"Le socle","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fthe-base","fr\u002Fdocs\u002F2.concepts\u002F4.the-base",false,{"title":54,"path":55,"stem":56,"children":57,"page":52},"Schéma","\u002Ffr\u002Fdocs\u002Fschema","fr\u002Fdocs\u002F3.schema",[58,62,66,70,74],{"title":59,"path":60,"stem":61},"Entités","\u002Ffr\u002Fdocs\u002Fschema\u002Fentities","fr\u002Fdocs\u002F3.schema\u002F1.entities",{"title":63,"path":64,"stem":65},"Vues","\u002Ffr\u002Fdocs\u002Fschema\u002Fviews","fr\u002Fdocs\u002F3.schema\u002F2.views",{"title":67,"path":68,"stem":69},"La carte d'identité","\u002Ffr\u002Fdocs\u002Fschema\u002Fcard","fr\u002Fdocs\u002F3.schema\u002F3.card",{"title":71,"path":72,"stem":73},"Standard Schema","\u002Ffr\u002Fdocs\u002Fschema\u002Fstandard-schema","fr\u002Fdocs\u002F3.schema\u002F4.standard-schema",{"title":75,"path":76,"stem":77},"Comment un schéma bouge","\u002Ffr\u002Fdocs\u002Fschema\u002Fevolution","fr\u002Fdocs\u002F3.schema\u002F5.evolution",{"title":79,"path":80,"stem":81,"children":82,"page":52},"Métier","\u002Ffr\u002Fdocs\u002Fbusiness","fr\u002Fdocs\u002F4.business",[83,87,91,95,99,103,107,111,115,119],{"title":84,"path":85,"stem":86},"Handlers","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fhandlers","fr\u002Fdocs\u002F4.business\u002F1.handlers",{"title":88,"path":89,"stem":90},"Les ports","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fports","fr\u002Fdocs\u002F4.business\u002F10.ports",{"title":92,"path":93,"stem":94},"Presenters","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fpresenters","fr\u002Fdocs\u002F4.business\u002F2.presenters",{"title":96,"path":97,"stem":98},"Collectors","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fcollectors","fr\u002Fdocs\u002F4.business\u002F3.collectors",{"title":100,"path":101,"stem":102},"Erreurs","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ferrors","fr\u002Fdocs\u002F4.business\u002F4.errors",{"title":104,"path":105,"stem":106},"Seeds","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fseeds","fr\u002Fdocs\u002F4.business\u002F5.seeds",{"title":108,"path":109,"stem":110},"Les faits","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ffacts","fr\u002Fdocs\u002F4.business\u002F6.facts",{"title":112,"path":113,"stem":114},"Le port Storage","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fstorage","fr\u002Fdocs\u002F4.business\u002F7.storage",{"title":116,"path":117,"stem":118},"Des écritures qui tiennent ou tombent ensemble","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ftogether","fr\u002Fdocs\u002F4.business\u002F8.together",{"title":120,"path":121,"stem":122},"Les repositories","\u002Ffr\u002Fdocs\u002Fbusiness\u002Frepositories","fr\u002Fdocs\u002F4.business\u002F9.repositories",{"title":124,"path":125,"stem":126,"children":127,"page":52},"Client","\u002Ffr\u002Fdocs\u002Fclient","fr\u002Fdocs\u002F5.client",[128,132,136,140,144],{"title":129,"path":130,"stem":131},"Queries & commands","\u002Ffr\u002Fdocs\u002Fclient\u002Fqueries-commands","fr\u002Fdocs\u002F5.client\u002F1.queries-commands",{"title":133,"path":134,"stem":135},"Formulaires","\u002Ffr\u002Fdocs\u002Fclient\u002Fforms","fr\u002Fdocs\u002F5.client\u002F2.forms",{"title":137,"path":138,"stem":139},"Session","\u002Ffr\u002Fdocs\u002Fclient\u002Fsession","fr\u002Fdocs\u002F5.client\u002F3.session",{"title":141,"path":142,"stem":143},"invoke","\u002Ffr\u002Fdocs\u002Fclient\u002Finvoke","fr\u002Fdocs\u002F5.client\u002F4.invoke",{"title":145,"path":146,"stem":147},"Back-office","\u002Ffr\u002Fdocs\u002Fclient\u002Fadmin","fr\u002Fdocs\u002F5.client\u002F5.admin",{"title":149,"path":150,"stem":151,"children":152,"page":52},"Infrastructure","\u002Ffr\u002Fdocs\u002Finfra","fr\u002Fdocs\u002F6.infra",[153,157,161,165,169,173,177,181,185],{"title":154,"path":155,"stem":156},"Le gradient","\u002Ffr\u002Fdocs\u002Finfra\u002Fgradient","fr\u002Fdocs\u002F6.infra\u002F1.gradient",{"title":158,"path":159,"stem":160},"Surfaces — REST & GraphQL","\u002Ffr\u002Fdocs\u002Finfra\u002Fsurfaces","fr\u002Fdocs\u002F6.infra\u002F2.surfaces",{"title":162,"path":163,"stem":164},"Déploiement","\u002Ffr\u002Fdocs\u002Finfra\u002Fdeployment","fr\u002Fdocs\u002F6.infra\u002F3.deployment",{"title":166,"path":167,"stem":168},"Hôtes","\u002Ffr\u002Fdocs\u002Finfra\u002Fhosts","fr\u002Fdocs\u002F6.infra\u002F4.hosts",{"title":170,"path":171,"stem":172},"Les sources","\u002Ffr\u002Fdocs\u002Finfra\u002Fsources","fr\u002Fdocs\u002F6.infra\u002F5.sources",{"title":174,"path":175,"stem":176},"Le cycle de vie","\u002Ffr\u002Fdocs\u002Finfra\u002Flifecycle","fr\u002Fdocs\u002F6.infra\u002F6.lifecycle",{"title":178,"path":179,"stem":180},"L'identité entre Fronds","\u002Ffr\u002Fdocs\u002Finfra\u002Fidentity","fr\u002Fdocs\u002F6.infra\u002F7.identity",{"title":182,"path":183,"stem":184},"Observabilité","\u002Ffr\u002Fdocs\u002Finfra\u002Fobservability","fr\u002Fdocs\u002F6.infra\u002F8.observability",{"title":186,"path":187,"stem":188},"Tests","\u002Ffr\u002Fdocs\u002Finfra\u002Ftesting","fr\u002Fdocs\u002F6.infra\u002F9.testing",{"id":190,"title":116,"body":191,"description":1019,"extension":1020,"meta":1021,"navigation":308,"path":117,"seo":1022,"stem":118,"__hash__":1023},"docs_fr\u002Ffr\u002Fdocs\u002F4.business\u002F8.together.md",{"type":192,"value":193,"toc":1013},"minimark",[194,198,222,537,556,565,570,584,592,598,608,676,683,695,715,719,742,881,895,898,902,905,944,947,953,969,986,990,997,1003,1009],[195,196,116],"h1",{"id":197},"des-écritures-qui-tiennent-ou-tombent-ensemble",[199,200,201,208,209,213,214,217,218,221],"p",{},[202,203,204],"a",{"href":113},[205,206,207],"code",{},"Storage\u003CPost>"," est le port dont chaque geste est ",[210,211,212],"strong",{},"une\ninstruction",", et une instruction est atomique sur tous les moteurs. ",[205,215,216],{},"Together"," est le port\ndont l'unité est un ",[210,219,220],{},"bloc"," : ce que la fonction a fait a lieu entièrement, ou pas du tout.",[223,224,229],"pre",{"className":225,"code":226,"language":227,"meta":228,"style":228},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","export default class TransferHandler {\n  constructor(private together: Together\u003C[Account, Ledger]>) {}\n\n  async move(from: string, to: string, amount: number) {\n    return this.together.run(async ([accounts, ledger]) => {\n      const debite = await accounts.findById(from);\n      await accounts.update(from, { balance: debite.balance - amount });\n      await ledger.create({ from, to, amount });\n    });\n  }\n}\n","ts","",[205,230,231,255,303,310,355,402,435,481,515,525,531],{"__ignoreMap":228},[232,233,236,240,243,247,251],"span",{"class":234,"line":235},"line",1,[232,237,239],{"class":238},"sVHd0","export",[232,241,242],{"class":238}," default",[232,244,246],{"class":245},"sbsja"," class",[232,248,250],{"class":249},"sbgvK"," TransferHandler",[232,252,254],{"class":253},"sP7_E"," {\n",[232,256,258,261,264,267,271,275,278,281,285,288,291,294,297,300],{"class":234,"line":257},2,[232,259,260],{"class":245},"  constructor",[232,262,263],{"class":253},"(",[232,265,266],{"class":245},"private",[232,268,270],{"class":269},"s99_P"," together",[232,272,274],{"class":273},"smGrS",":",[232,276,277],{"class":249}," Together",[232,279,280],{"class":253},"\u003C",[232,282,284],{"class":283},"su5hD","[",[232,286,287],{"class":249},"Account",[232,289,290],{"class":253},",",[232,292,293],{"class":249}," Ledger",[232,295,296],{"class":283},"]",[232,298,299],{"class":253},">)",[232,301,302],{"class":253}," {}\n",[232,304,306],{"class":234,"line":305},3,[232,307,309],{"emptyLinePlaceholder":308},true,"\n",[232,311,313,316,320,322,325,327,331,333,336,338,340,342,345,347,350,353],{"class":234,"line":312},4,[232,314,315],{"class":245},"  async",[232,317,319],{"class":318},"sVXei"," move",[232,321,263],{"class":253},[232,323,324],{"class":269},"from",[232,326,274],{"class":273},[232,328,330],{"class":329},"sZMiF"," string",[232,332,290],{"class":253},[232,334,335],{"class":269}," to",[232,337,274],{"class":273},[232,339,330],{"class":329},[232,341,290],{"class":253},[232,343,344],{"class":269}," amount",[232,346,274],{"class":273},[232,348,349],{"class":329}," number",[232,351,352],{"class":253},")",[232,354,254],{"class":253},[232,356,358,361,365,368,371,373,377,380,383,386,389,391,394,397,400],{"class":234,"line":357},5,[232,359,360],{"class":238},"    return",[232,362,364],{"class":363},"s39Yj"," this",[232,366,367],{"class":253},".",[232,369,370],{"class":283},"together",[232,372,367],{"class":253},[232,374,376],{"class":375},"sGLFI","run",[232,378,263],{"class":379},"skxfh",[232,381,382],{"class":245},"async",[232,384,385],{"class":253}," ([",[232,387,388],{"class":269},"accounts",[232,390,290],{"class":253},[232,392,393],{"class":269}," ledger",[232,395,396],{"class":253},"])",[232,398,399],{"class":245}," =>",[232,401,254],{"class":253},[232,403,405,408,412,415,418,421,423,426,428,430,432],{"class":234,"line":404},6,[232,406,407],{"class":245},"      const",[232,409,411],{"class":410},"s_hVV"," debite",[232,413,414],{"class":273}," =",[232,416,417],{"class":238}," await",[232,419,420],{"class":283}," accounts",[232,422,367],{"class":253},[232,424,425],{"class":375},"findById",[232,427,263],{"class":379},[232,429,324],{"class":283},[232,431,352],{"class":379},[232,433,434],{"class":253},";\n",[232,436,438,441,443,445,448,450,452,454,457,460,462,464,466,469,472,474,477,479],{"class":234,"line":437},7,[232,439,440],{"class":238},"      await",[232,442,420],{"class":283},[232,444,367],{"class":253},[232,446,447],{"class":375},"update",[232,449,263],{"class":379},[232,451,324],{"class":283},[232,453,290],{"class":253},[232,455,456],{"class":253}," {",[232,458,459],{"class":379}," balance",[232,461,274],{"class":253},[232,463,411],{"class":283},[232,465,367],{"class":253},[232,467,468],{"class":283},"balance",[232,470,471],{"class":273}," -",[232,473,344],{"class":283},[232,475,476],{"class":253}," }",[232,478,352],{"class":379},[232,480,434],{"class":253},[232,482,484,486,488,490,493,495,498,501,503,505,507,509,511,513],{"class":234,"line":483},8,[232,485,440],{"class":238},[232,487,393],{"class":283},[232,489,367],{"class":253},[232,491,492],{"class":375},"create",[232,494,263],{"class":379},[232,496,497],{"class":253},"{",[232,499,500],{"class":283}," from",[232,502,290],{"class":253},[232,504,335],{"class":283},[232,506,290],{"class":253},[232,508,344],{"class":283},[232,510,476],{"class":253},[232,512,352],{"class":379},[232,514,434],{"class":253},[232,516,518,521,523],{"class":234,"line":517},9,[232,519,520],{"class":253},"    }",[232,522,352],{"class":379},[232,524,434],{"class":253},[232,526,528],{"class":234,"line":527},10,[232,529,530],{"class":253},"  }\n",[232,532,534],{"class":234,"line":533},11,[232,535,536],{"class":253},"}\n",[199,538,539,540,543,544,547,548,551,552,555],{},"Résolu par type, comme ",[205,541,542],{},"RepositoryOf\u003CE>",", ",[205,545,546],{},"Facade\u003CH>"," et ",[205,549,550],{},"Emit\u003CF>"," — le type nomme le sujet, le\nconteneur tient la réalisation. Rien à enregistrer, et rien d'ambiant : aucun décorateur ne\nrend un ",[205,553,554],{},"storage.create()"," ordinaire transactionnel dans votre dos, donc le bloc est visible là\noù on le lit.",[199,557,558,559,547,561,564],{},"À l'intérieur, on est dans le vocabulaire habituel. ",[205,560,388],{},[205,562,563],{},"ledger"," sont les mêmes\nports d'entité gardés que les repositories transmettent, et tous les juges tournent encore :\nune valeur que l'entité refuse est refusée là aussi.",[566,567,569],"h2",{"id":568},"deux-réalisations-et-le-démarrage-dit-laquelle","Deux réalisations, et le démarrage dit laquelle",[199,571,572,573,577,578,583],{},"La déclaration nomme ses membres. Où ces membres ",[574,575,576],"em",{},"vivent"," est une décision de\n",[202,579,580],{"href":171},[205,581,582],{},"sources:",", et c'est elle qui décide de ce que le cadre peut\npromettre :",[223,585,590],{"className":586,"code":588,"language":589},[587],"language-text","Account+LedgerTogether — transaction, source 'db'\nAccount+LedgerTogether — compensated: account in 'db', ledger in 'accounting' — no isolation\n","text",[205,591,588],{"__ignoreMap":228},[199,593,594,597],{},[210,595,596],{},"Un seul moteur"," — les membres sont reconstruits sur une vraie transaction. Le moteur\ndonne le retour arrière et l'isolation, et ça ne coûte rien.",[199,599,600,603,604,607],{},[210,601,602],{},"Plusieurs moteurs"," — une transaction atteint un moteur, donc il n'y en a pas. Le cadre\ngarde l'image d'avant de chaque écriture et rejoue les inverses en ordre inverse. Le port a\nun jeu de gestes fixe, et c'est ce qui rend l'inverse ",[210,605,606],{},"dérivable"," plutôt que déclaré :",[609,610,611,624],"table",{},[612,613,614],"thead",{},[615,616,617,621],"tr",{},[618,619,620],"th",{},"écriture",[618,622,623],{},"son inverse",[625,626,627,641,654,666],"tbody",{},[615,628,629,635],{},[630,631,632],"td",{},[205,633,634],{},"create(x)",[630,636,637,640],{},[205,638,639],{},"delete(x.id)"," — la ligne est rendue, donc ça ne coûte rien",[615,642,643,648],{},[630,644,645],{},[205,646,647],{},"update(id, patch)",[630,649,650,653],{},[205,651,652],{},"update(id, avant)"," — une lecture d'abord",[615,655,656,661],{},[630,657,658],{},[205,659,660],{},"delete(id)",[630,662,663,653],{},[205,664,665],{},"create(ligne)",[615,667,668,673],{},[630,669,670],{},[205,671,672],{},"upsertAll(page)",[630,674,675],{},"restaurer ce qui était là, supprimer le reste — une lecture pour la page",[199,677,678,679,682],{},"C'est pour ça que ce n'est pas une saga : une saga demande à son auteur un ",[205,680,681],{},"undo"," par étape,\nparce que ses étapes sont du code quelconque. Ici, non.",[684,685,686,692],"warning",{},[199,687,688,691],{},[210,689,690],{},"Le tout-ou-rien tient des deux côtés. L'isolation, non."," Sous transaction, personne à\nl'extérieur ne peut voir le bloc à moitié fait. En compensé, si — entre deux écritures un\nlecteur voit la moitié, et le retour arrière la remet ensuite.",[199,693,694],{},"Le démarrage énonce la réalisation qu'il a construite plutôt que de vous laisser supposer la\nplus forte.",[684,696,697],{},[199,698,699,702,703,706,707,710,711,714],{},[210,700,701],{},"Un fact annoncé dans un frame n'est pas couvert."," ",[205,704,705],{},"Emit\u003CT>"," se résout hors du bloc,\ndonc une annonce part au moment où elle est faite — y compris depuis un frame qui se\ndéroule ensuite. Les abonnés auront agi sur quelque chose qui n'a pas eu lieu. Annoncez\n",[210,708,709],{},"après"," le retour de ",[205,712,713],{},"run()",", quand le bloc a déjà tenu.",[566,716,718],{"id":717},"couvrir-ce-quécrit-un-collaborateur","Couvrir ce qu'écrit un collaborateur",[199,720,721,722,725,726,729,730,733,734,737,738,741],{},"Une liste d'entités couvre ce que ",[574,723,724],{},"votre"," bloc écrit. Une seconde liste nomme des\n",[210,727,728],{},"fournisseurs"," — un service, un ",[202,731,732],{"href":121},"repository",", un\n",[202,735,736],{"href":50},"miroir"," — reconstruits dans le cadre pour que ce qu'",[574,739,740],{},"eux","\nécrivent soit couvert aussi :",[223,743,745],{"className":225,"code":744,"language":227,"meta":228,"style":228},"constructor(private together: Together\u003C[RateCard, Ledger], [RateMirror]>) {}\n\nawait this.together.run(async ([rates, ledger], [mirror]) => {\n  await mirror.refresh();          \u002F\u002F ses pages sont sous le même retour arrière\n  await ledger.create({ … });\n});\n",[205,746,747,779,783,826,849,873],{"__ignoreMap":228},[232,748,749,752,755,757,760,762,765,767,770,773,776],{"class":234,"line":235},[232,750,751],{"class":375},"constructor",[232,753,754],{"class":283},"(private together: Together",[232,756,280],{"class":273},[232,758,759],{"class":283},"[RateCard",[232,761,290],{"class":253},[232,763,764],{"class":283}," Ledger]",[232,766,290],{"class":253},[232,768,769],{"class":283}," [RateMirror]",[232,771,772],{"class":273},">",[232,774,775],{"class":283},") ",[232,777,778],{"class":253},"{}\n",[232,780,781],{"class":234,"line":257},[232,782,309],{"emptyLinePlaceholder":308},[232,784,785,788,790,792,794,796,798,800,802,804,807,809,811,814,817,820,822,824],{"class":234,"line":305},[232,786,787],{"class":238},"await",[232,789,364],{"class":363},[232,791,367],{"class":253},[232,793,370],{"class":283},[232,795,367],{"class":253},[232,797,376],{"class":375},[232,799,263],{"class":283},[232,801,382],{"class":245},[232,803,385],{"class":253},[232,805,806],{"class":269},"rates",[232,808,290],{"class":253},[232,810,393],{"class":269},[232,812,813],{"class":253},"],",[232,815,816],{"class":253}," [",[232,818,819],{"class":269},"mirror",[232,821,396],{"class":253},[232,823,399],{"class":245},[232,825,254],{"class":253},[232,827,828,831,834,836,839,842,845],{"class":234,"line":312},[232,829,830],{"class":238},"  await",[232,832,833],{"class":283}," mirror",[232,835,367],{"class":253},[232,837,838],{"class":375},"refresh",[232,840,841],{"class":379},"()",[232,843,844],{"class":253},";",[232,846,848],{"class":847},"sutJx","          \u002F\u002F ses pages sont sous le même retour arrière\n",[232,850,851,853,855,857,859,861,863,866,869,871],{"class":234,"line":357},[232,852,830],{"class":238},[232,854,393],{"class":283},[232,856,367],{"class":253},[232,858,492],{"class":375},[232,860,263],{"class":379},[232,862,497],{"class":253},[232,864,865],{"class":379}," … ",[232,867,868],{"class":253},"}",[232,870,352],{"class":379},[232,872,434],{"class":253},[232,874,875,877,879],{"class":234,"line":404},[232,876,868],{"class":253},[232,878,352],{"class":283},[232,880,434],{"class":253},[199,882,883,886,887,890,891,894],{},[205,884,885],{},"RateMirror"," écrit par ",[205,888,889],{},"Storage\u003CRateCard>",", donc il reçoit le storage du cadre par son\nconstructeur ordinaire. Pas une ligne de ",[205,892,893],{},"Mirror"," ne sait qu'un cadre existe.",[199,896,897],{},"Deux listes plutôt qu'une, parce que dans une signature une entité et une classe s'écrivent\ntoutes deux comme un nom et que leurs types ne les séparent pas. Ce sont deux faits\ndifférents de toute façon : ce que le retour arrière couvre, et ce qui est reconstruit pour\nque ce soit vrai.",[566,899,901],{"id":900},"ce-quun-cadre-refuse","Ce qu'un cadre refuse",[199,903,904],{},"Au démarrage, pour que vous ne le découvriez jamais au premier appel :",[609,906,907,915],{},[612,908,909],{},[615,910,911,913],{},[618,912],{},[618,914],{},[625,916,917,928,936],{},[615,918,919,925],{},[630,920,921,922],{},"un membre dont le frond est déclaré dans ",[205,923,924],{},"remotes:",[630,926,927],{},"il n'enregistre aucun stockage ici — rien à consigner, rien à défaire",[615,929,930,933],{},[630,931,932],{},"un nom qui ne désigne rien",[630,934,935],{},"une faute de frappe, dont le seul autre symptôme est un cadre discrètement amputé d'un membre",[615,937,938,941],{},[630,939,940],{},"un fournisseur qui écrit une entité absente de la première liste",[630,942,943],{},"ses écritures échapperaient au retour arrière",[199,945,946],{},"Deux autres à l'appel :",[199,948,949,952],{},[210,950,951],{},"Un cadre ouvert dans un autre."," Sur un seul moteur, la seconde transaction attend la\npremière et l'appel se bloque — mesuré, cinq secondes sans réponse ; répartis sur deux\nmoteurs, le même code répond. Deux cadres qui doivent tous deux tenir n'en font qu'un, et\nsa liste de membres est l'union.",[199,954,955,962,963,965,966,968],{},[210,956,957,958,961],{},"Un ",[202,959,960],{"href":109},"fait"," annoncé depuis l'intérieur."," Annoncer, c'est\ndistribuer : chaque abonné l'a reçu et le transporteur l'a déjà mis sur le fil, alors que\nles écritures peuvent encore être reprises. Annoncer après le retour de ",[205,964,713],{},", qui est le\nmoment où c'est vrai. Différer jusqu'au commit était l'autre option, écartée : ",[205,967,705],{}," se\ncomporterait autrement selon l'endroit d'où on l'appelle, et la fenêtre ouverte entre le\ncommit et l'annonce n'a d'autre remède qu'une table d'attente.",[199,970,971,972,975,976,981,982,985],{},"Et dans un cadre compensé seulement : ",[205,973,974],{},"upsert"," sur une entité qui déclare une\ncontrainte ",[202,977,978],{"href":60},[205,979,980],{},"unique"," en plus de sa clé. L'inverse d'un upsert est\ndérivable exactement quand le conflit porte sur la clé ; le ",[205,983,984],{},"ON DUPLICATE KEY UPDATE"," de\nMySQL se déclenche sur n'importe quelle contrainte unique, donc la question se pose à votre\ndéclaration et jamais au moteur.",[566,987,989],{"id":988},"là-où-le-gradient-sarrête","Là où le gradient s'arrête",[199,991,992,993,996],{},"Déclarer ",[205,994,995],{},"Together\u003C[Account, Ledger]>",", c'est dire que ces deux-là ne peuvent pas être\nséparées par un changement de topologie. C'est un vrai coût, et c'est l'intérêt : c'est le\nseul endroit où déplacer une frontière est refusé à voix haute au lieu d'affaiblir une\ngarantie en silence.",[199,998,999,1000,1002],{},"Quand deux choses vivent réellement à part et doivent toutes deux finir écrites, ce n'est pas\nun cadre — c'est un ",[202,1001,960],{"href":109}," : valider une moitié, annoncer, et\nlaisser l'abonné valider l'autre. La compensation vous appartient alors, et le framework ne\nprétend pas le contraire.",[199,1004,1005,1006,367],{},"Suite : ",[202,1007,1008],{"href":121},"Repositories",[1010,1011,1012],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}",{"title":228,"searchDepth":257,"depth":257,"links":1014},[1015,1016,1017,1018],{"id":568,"depth":257,"text":569},{"id":717,"depth":257,"text":718},{"id":900,"depth":257,"text":901},{"id":988,"depth":257,"text":989},"Together — le port dont l'unité est un bloc, ses deux réalisations, et la ligne de démarrage qui dit laquelle vous avez.","md",{},{"title":116,"description":1019},"aeiM3jZqxpEc5cuOAN51ktSJChXCjbovJHhU3e_dd1M",1788560232360]