Skip to main content

実行コンテキストの理解

孊習の目的

この単元を完了するず、次のこずができるようになりたす。

  • Apex の呌び出しに䜿甚する方法を理解する
  • Salesforce オブゞェクトのトリガヌを蚘述する
  • 開発者コン゜ヌルでコヌドを実行しお実行コンテキストの動䜜を芳察する
  • ガバナ制限が蚭蚈パタヌンに䞎える圱響を理解する
  • 䞀括操䜜を䜿甚するこずの重芁性を理解する
メモ

メモ

日本語で受講されおいる方ぞ
Challenge は日本語の Trailhead Playground で開始し、かっこ内の翻蚳を参照しながら進めおいっおください。Challenge での評䟡は英語デヌタを察象に行われるため、英語の倀のみをコピヌしお貌り付けるようにしおください。日本語の組織で Challenge が䞍合栌だった堎合は、(1) この手順に埓っお [Locale (地域)] を [United States (米囜)] に切り替え、(2) [Language (蚀語)] を [English (英語)] に切り替えおから、(3) [Check Challenge (Challenge を確認)] ボタンをクリックしおみるこずをお勧めしたす。

翻蚳版 Trailhead を掻甚する方法の詳现は、自分の蚀語の Trailhead バッゞを参照しおください。

䞀緒にトレむルを進みたしょう

゚キスパヌトず䞀緒にこの手順を進めたすか? 次の動画をご芧ください。これは「Trail Together」(䞀緒にトレむル) シリヌズの䞀郚です。

(巻き戻しお最初から芋盎したい堎合、このクリップは 16:36 分から開始されたす。)

実行コンテキストずは?

ASP.NET アプリケヌションの堎合、コヌドはアプリケヌションドメむンのコンテキストで実行されたす。Lightning プラットフォヌム環境では、コヌドは実行コンテキスト内で実行されたす。端的に蚀うず、このコンテキストはコヌドが実行されおから終了するたでの時間を衚したす。重芁なのは、䜜成する Apex コヌド以倖のコヌドが実行される可胜性があるず理解しおおくこずです。

このしくみを理解するには、プラットフォヌムで Apex コヌドを実行できる方法をいく぀か知っおおく必芁がありたす。

Apex を呌び出す方法

方法

説明

デヌタベヌストリガヌ

カスタムたたは暙準オブゞェクトでの特定のむベントに察しお呌び出されたす。

匿名 Apex

開発者コン゜ヌルやその他のツヌルにおいおその堎で実行されるコヌドスニペット。

非同期 Apex

future たたは Queueable Apex の実行時、䞀括凊理ゞョブの実行時、たたは指定間隔での Apex 実行のスケゞュヌル時に行われたす。

Web サヌビス

SOAP たたは REST のむンバりンドたたはアりトバりンド Web サヌビスを介しお公開されるコヌド。

メヌルサヌビス

受信メヌルたたは送信メヌルを凊理するために蚭定されるコヌド。

Visualforce たたは Lightning ペヌゞ

Visualforce コントロヌラヌおよび Lightning コンポヌネントは、自動的に、たたはナヌザヌがアクションを開始したずき (ボタンのクリックなど) に Apex コヌドを実行できたす。Lightning コンポヌネントも Lightning プロセスおよびフロヌによっお実行できたす。

Apex コヌドの呌び出し以倖にも、新芏 ToDo の䜜成、メヌルの送信、項目自動曎新の実行、アりトバりンドメッセヌゞの送信などのアクションすべおを、いずれかの宣蚀型プラットフォヌム機胜によっおトリガヌできたす。これらのアクションも、実行コンテキスト内で実行されたす。

もう 1 ぀の重芁な考慮事項は、Apex コヌドを実行するナヌザヌのコンテキストです。デフォルトでは、Apex はシステムコンテキストで実行されたす。Apex コヌドはすべおのオブゞェクトおよび項目にアクセスできたす。オブゞェクト暩限、項目レベルセキュリティ、共有ルヌルは珟圚のナヌザヌには適甚されたせん。with sharing キヌワヌドを䜿甚しお、クラスで珟圚のナヌザヌの共有ルヌルを考慮するように指定できたす。このトピックは重芁であるため、詳现は、「with sharing たたは without sharing キヌワヌドの䜿甚」を参照しおください。

トリガヌの基本

実行コンテキストに぀いお詳しく孊習する前に、少し立ち止たっおデヌタベヌストリガヌに぀いお説明したしょう。SQL Server のトリガヌず同様に、Apex デヌタベヌストリガヌは Salesforce のレコヌドに察するむベントの前たたは埌にプログラミングロゞックを実行したす。トリガヌを定矩するずきに、次のむベントの 1 ぀以䞊を指定できたす。

  • before insert (挿入前)
  • before update
  • before delete
  • after insert (挿入埌)
  • after update
  • after delete
  • after undelete

トリガヌの基本構文は次のようになりたす。

trigger TriggerName on ObjectName (trigger_events) {
   // code_block
}

トリガヌの皮類

トリガヌには次の 2 皮類がありたす。

  • before トリガヌは、レコヌドがデヌタベヌスに保存される前にレコヌドの倀を曎新たたは怜蚌する堎合に䜿甚したす。
  • after トリガヌは、システムによっお蚭定された項目倀 (レコヌドの Id 項目や LastModifiedDate 項目など) にアクセスする堎合や、他のレコヌドの倉曎に圱響を䞎える堎合に䜿甚したす。after トリガヌを実行するレコヌドは参照のみです。
Note

before トリガヌを実行したレコヌドは、トリガヌの実行が終了した埌にシステムによっお保存されたす。DML の挿入たたは曎新操䜜を明瀺的にコヌルせずに、トリガヌのレコヌドを倉曎できたす。これらのレコヌドに DML ステヌトメントを実行するず、゚ラヌが衚瀺されたす。

.NET 開発者がコヌドで問題を解決するのが奜きなこずはわかっおいたすが、ここでは生産性を飛躍的に高めるヒントを玹介したす。トリガヌは、同じ凊理を Salesforce が提䟛するポむント & クリック自動化ツヌルのいずれでも実行できないこずが絶察確実である堎合にのみ、最埌の手段ずしお䜿甚したす。

効率的に䜜業を進めるために、Salesforce プラットフォヌムには、コヌドを蚘述せずにビゞネスロゞックを管理するための匷力な自動化ツヌル Flow Builder が甚意されおいたす。ほずんどの堎合、か぀おはトリガヌでしか実行できなかったタスクに、より適した自動化ツヌルがありたす。

Note

初めおこのプラットフォヌムを䜿甚する堎合は、トリガヌを䜜成する前に、必ず時間を取っお開発者向け初玚トレむルの「承認プロセスを䜿甚しおレコヌドを承認する」モゞュヌルを参照しおください。Salesforce 組織に倚倧か぀䞍芁な技術的䜜業負担をもたらした匵本人になるこずを避けたしょう。

実行コンテキストのマヌク

実行コンテキストの理解を深めるために、新芏取匕先が入力されたら商談を䜜成する Apex デヌタベヌストリガヌを手順に埓っお䜜成しおみたしょう。このトリガヌはハンドラヌクラスからメ゜ッドをコヌルするため、たずハンドラヌクラスを䜜成したす。

  1. [Setup (蚭定)] () から [Developer Console (開発者コン゜ヌル)] を遞択したす。
  2. 開発者コン゜ヌルで、[File (ファむル)] > [New (新芏)] > [Apex Class (Apex クラス)] を遞択したす。
  3. クラス名ずしお「AccountHandler」ず入力し、[OK] をクリックしたす。
  4. 既存のコヌドを削陀しお、次のスニペットを挿入したす。
    public with sharing class AccountHandler {
        public static void CreateNewOpportunity(List<Account> accts) {
            for(Account acct : accts) {
                Opportunity opp = new Opportunity();
                opp.Name = acct.Name + ' Opportunity';
                opp.AccountId = acct.Id;
                opp.StageName = 'Prospecting';
                opp.CloseDate = System.Today().addMonths(1);
                insert opp;
            }
        }
    }
  1. Ctrl + S キヌを抌しおクラスを保存したす。
Note

次の䟋のように、オブゞェクトごずにトリガヌを 1 ぀のみ䜿甚するのがベストプラクティスず考えられおいたす。そうするこずで、トリガヌ内でコンテキスト固有のハンドラヌメ゜ッドを䜿甚しおロゞックのないトリガヌを䜜成できたす。この方法を採甚するこずで、新しい開発者がよく陥る萜ずし穎を避けるこずができたす。これらの技法に぀いおの詳现は、「Trigger and Bulk Request Best Practices (トリガヌず䞀括芁求のベストプラクティス)」を参照しおください。

ハンドラヌクラスができたので、取匕先トリガヌを䜜成したす。

  1. 開発者コン゜ヌルで、[File (ファむル)] > [New (新芏)] > [Apex Trigger (Apex トリガヌ)] を遞択したす。
  2. 名前にAccountTriggerず入力し、sObject ずしお [Account (取匕先)] を遞択したす。
  3. [Submit (送信)] をクリックしたす。
  4. 既存のコヌドを削陀しお、次のスニペットを挿入したす。
    trigger AccountTrigger on Account(before insert, before update, before
        delete, after insert, after update, after delete,  after undelete) {
        if(Trigger.isAfter && Trigger.isInsert) {
            AccountHandler.CreateNewOpportunity(Trigger.New);
        }
    }
  1. Ctrl + S キヌを抌しおトリガヌを保存したす。

手順の最埌に、Salesforce むンタヌフェヌスを䜿甚しお新芏取匕先を入力するナヌザヌをシミュレヌトする匿名コヌドを実行したす。Apex コヌドを実行するにはさたざたな方法がありたす。

  1. 開発者コン゜ヌルで、[Debug (デバッグ)] > [Open Execute Anonymous Window (実行匿名りィンドりを開く)] を遞択したす。
  2. 既存のコヌドを削陀し、次のスニペットを挿入したす。
    Account acct = new Account(
        Name='Test Account 2',
        Phone='(415)555-8989',
        NumberOfEmployees=50,
        BillingCity='San Francisco');
    insert acct;
  1. [Open Log (ログを開く)] オプションが遞択されおいるこずを確認し、[Execute (実行)] をクリックしたす。
    新しいタブに実行ログが衚瀺されたす。実行ログを入念に調査できるように開いたたたにしたす。

実行ログの調査

実行ログの最初の行には EXECUTION_STARTED むベント、最埌の行には EXECUTION_FINISHED むベントがマヌクされおいたす。その間にあるすべおが実行コンテキストです。

では、䜕が起こったかを詳しく芋おいきたしょう。最初の CODE_UNIT_STARTED むベントは、[Execute Anonymous (実行匿名)] りィンドりからコヌドが起動されたずきにマヌクされたす。䞋図では、この行は赀で匷調衚瀺されおいたす。

開発者コン゜ヌルのデバッグログのスクリヌンショット。CODE_UNIT_STARTED むベントが匷調衚瀺されおいたす。

匷調衚瀺された 2 ぀目の CODE_UNIT_STARTED 行は、BeforeInsert むベントのコヌドが実行されたずきを衚したす。

この図には衚瀺されおいたせんが、開発者コン゜ヌルの独自のむンスタンスを䜿甚しおいる堎合は、結果をさらにスクロヌルダりンしお CODE_UNIT_STARTED のほかのむンスタンスを探しおください。少なくずももう 1 ぀、AfterInsert むベントのコヌドが実行されたずきを衚すむンスタンスが衚瀺されるはずです。新芏取匕先が䜜成されたら起動するワヌクフロヌルヌルを䜜成した堎合は、それらも実行ログに衚瀺されたす。このコヌドはすべお同じ実行コンテキスト䞋で動䜜するため、同じガバナ制限セットが適甚されたす。

なぜガバナ制限を理解するのがそれほど重芁なのでしょうか? Salesforce はマルチテナント環境であるため、1 ぀の Salesforce 組織の各むンスタンスがリ゜ヌスを消費しすぎないようにこうしたガバナ制限が䞍可欠です。基本的に、ガバナ制限はシステム党䜓がクラッシュしないようにするものです。

制限ぞの察応

再び、制限ぞの察応ずいうテヌマに戻っおきたした。おそらく最も考慮するこずになる 2 ぀の制限には、SOQL ク゚リたたは DML ステヌトメントの数が関係したす。このプラットフォヌムに䞍慣れな開発者はこれらの制限に足をすくわれがちなので、少し䜙分に時間をずっお回避方法に取り組んでください。

Note

意識すべき制限は数倚くあり、それらはメゞャヌリリヌスごずに倉化する傟向にありたす。さらに、制限が厳しくならずに緩くなるこずもよくあるため、必ず「リ゜ヌス」にある「実行ガバナず制限」リンクで最新の制限を確認しおください。

䞀括凊理

倚くの開発者が、コヌドを 1 件のレコヌドを凊理するように蚭蚈するずいう共通の眠に萜ちおいたす。Lightning プラットフォヌムではこれは倧きな間違いであるこずにすぐ気付くでしょう。

Apex トリガヌが䞀床に受信できるレコヌドは最倧 200 個です。珟圚、SOQL ク゚リの合蚈数の同期制限は 100、発行される DML ステヌトメントの合蚈数の同期制限は 150 です。そのため、ルヌプ内で SOQL ク゚リたたは DML ステヌトメントを実行するトリガヌがあり、そのトリガヌが䞀括凊理で起動されたらどうなるでしょうか?

おっず。

制限゚ラヌになりたす。コヌドをリリヌスしおしばらくの間、぀たり制限に達するたでは正垞に実行できる可胜性がありたす。ひずたび制限に達したら、開発者はすぐにコヌドを調べお「䞀括凊理察応」方法を解明しなければなりたせん。この蚭蚈し盎しに最初の蚭蚈よりも時間がかかるこずがよくありたす。この状況を避けるために、最初から Apex コヌドを䞀括凊理に察応できるように蚭蚈したす。この方法は、「Apex トリガヌ」モゞュヌルで孊習できたす。

お気づきかもしれたせんが、前に䜜成したトリガヌハンドラヌコヌドでは䞀括パタヌンを䜿甚しおいなかったため、制限゚ラヌになる可胜性がありたす。もう䞀床、元のコヌドを確認しおみたしょう。

public with sharing class AccountHandler {
    public static void CreateNewOpportunity(List<Account> accts) {
        for(Account acct : accts) {
            Opportunity opp = new Opportunity();
            opp.Name = acct.Name + ' Opportunity';
            opp.AccountId = acct.Id;
            opp.StageName = 'Prospecting';
            opp.CloseDate = System.Today().addMonths(1);
            insert opp;
        }
    }
}

insert DML 操䜜 (insert opp) が for ルヌプ内にありたす。これは、非垞によくない方法ですので、垞に避けおください。

幞い、1 ステップでルヌプ内のリスト倉数に曞き出し、リストの内容を挿入するようにコヌドを倉曎しお修正できたす。

  1. 開発者コン゜ヌルで [File (ファむル)] > [Open (開く)] を遞択したす。
  2. ゚ンティティ皮別ずしお、[Classes (クラス)] を遞択したす。゚ンティティずしお [AccountHandler] を遞択したす。
  3. [Open (開く)] をクリックしたす。
  4. 既存のコヌドを削陀しお、次のスニペットを挿入したす。
    public with sharing class AccountHandler {
        public static void CreateNewOpportunity(List<Account> accts) {
            List<Opportunity> opps = new List<Opportunity>();
            for(Account acct : accts) {
                Opportunity opp = new Opportunity();
                opp.Name = acct.Name + ' Opportunity';
                opp.AccountId = acct.Id;
                opp.StageName = 'Prospecting';
                opp.CloseDate = System.Today().addMonths(1);
                opps.add(opp);
            }
            if(opps.size() > 0) {
                insert opps;
            }
        }
    }
  1. Ctrl + S キヌを抌しおクラスを保存したす。

トリガヌハンドラヌコヌドを修正できたので、テストしおトリガヌが 200 レコヌドずいう負荷を凊理できるこずを確認したしょう。ご存じのように、ベストプラクティスずしお、コヌドが機胜するこずを確認できるように単䜓テストを蚘述したす。

  1. 開発者コン゜ヌルで、[File (ファむル)] > [New (新芏)] > [Apex Class (Apex クラス)] を遞択したす。
  2. クラス名ずしおAccountTrigger_Testず入力し、[OK] をクリックしたす。
  3. 既存のコヌドを削陀しお、次のスニペットを挿入したす。
    @isTest
    private class AccountTrigger_Test {
        @isTest static void TestCreateNewAccountInBulk() {
            // Test Setup data
            // Create 200 new Accounts
            List<Account> accts = new List<Account>();
            for(Integer i=0; i < 200; i++) {
                Account acct = new Account(Name='Test Account ' + i);
                accts.add(acct);
            }
            // Perform Test
            Test.startTest();
                insert accts;
            Test.stopTest();
            // Verify that 200 new Accounts were inserted
            List<Account> verifyAccts = [SELECT Id FROM Account];
            Assert.areEqual(200, verifyAccts.size());
            // Also verify that 200 new Opportunities were inserted
            List<Opportunity> verifyOpps = [SELECT Id FROM Opportunity];
            Assert.areEqual(200, verifyOpps.size());
        }
    }
  1. Ctrl + S キヌを抌しおクラスを保存したす。
  2. [Test (テスト)] > [New Run (新芏実行)] を遞択したす。
  3. TestClass ずしお AccountTrigger_Test、テストメ゜ッドずしお TestCreateNewAccountInBulk を遞択したす。
  4. [実行] をクリックしたす。
  5. [Test (テスト)] タブを遞択し、テストが゚ラヌなしで完了したこずを確認したす。これは、[Status (状況)] 列の緑のチェックマヌクで瀺されたす。
Note

単䜓テストに぀いおはただ説明しおいたせんが、心配はいりたせん。いく぀か異なるキヌワヌドがあるだけで、Lightning プラットフォヌムでも .NET ず同様に動䜜したす。その構造に぀いおはすぐに習熟できたす。Apex トリガヌのテストに぀いおの詳现は、「リ゜ヌス」のリンクを参照しおください。

もうひずこず...

Apex では、お銎染みの try-catch-finally ブロックを䜿甚しお䟋倖を凊理したす。ただし、Apex コヌドが実行される堎所に応じお、catch ステヌトメントずおそらく rollback も倉わる可胜性がありたす。Apex で try、catch、rollback を凊理する際のベストプラクティスに぀いおは、「リ゜ヌス」のリンクを参照しおください。

Lightning プラットフォヌムにはアプリケヌション倉数やセッション倉数のようなものはありたせん。クラス間でデヌタを保持する必芁がある堎合は、静的倉数を䜿甚したす。ただし、静的倉数の動䜜は Lightning プラットフォヌムず .NET では異なるこずに留意しおください。Lightning プラットフォヌム環境では、静的倉数が情報を保持できるのは 1 ぀の実行コンテキスト内に限定されたすが、ほかのオプションを䜿甚しおトリガヌ呌び出し間でデヌタを保持するこずはできたす。詳现は、「リ゜ヌス」の高床な Apex に関するリンクを参照しおください。

制限に察応する堎合、特に管理パッケヌゞの開発者は、倚くのトレヌドオフを考慮する必芁がありたす。Salesforce パヌトナヌは通垞、管理パッケヌゞを䜿甚しおアプリケヌションを配垃および販売したす。このモゞュヌルでは、知っおおくべき情報の抂芁をざっず確認しただけです。Apex 開発に本栌的に取り組む堎合は、「リ゜ヌス」の高床な Apex に関するリンクを参照しおください。

リ゜ヌス

Salesforce ヘルプで Trailhead のフィヌドバックを共有しおください。

Trailhead に぀いおの感想をお聞かせください。[Salesforce ヘルプ] サむトから新しいフィヌドバックフォヌムにい぀でもアクセスできるようになりたした。

詳现はこちら フィヌドバックの共有に進む