>

응용 프로그램 범위에 CFC를 저장하는 것에 대한 많은 게시물을 읽었으며 CFC가 데이터를 저장하면 응용 프로그램 범위에 있으면 안된다는 것을 이해합니다. 유틸리티가 아닌 것을 수행하는 모든 CFC는 사용자 이름이나 이메일 주소와 같은 매개 변수를 전달할 때 데이터를 저장하므로 유틸리티가 아닌 cfc에 대해 응용 프로그램 범위를 사용하지 않을 때와 시간을 얻지 못합니다.

내 질문은 내가 posthandler.cfc 를 가지고 있다는 것입니다  사용자의 게시물을 처리하는 약 500 줄의 코드 구성 요소 (이 사이트에 게시 된 각 질문을 처리하는 것처럼). posthandler.cfc  구성 요소 :

  • 사용자가 제출 한 모든 이미지와 텍스트를 '청소'
  • 이미지를 올바른 폴더에 배치합니다
  • 모든 텍스트를 데이터베이스에 씁니다
  • 소식을 볼 수있는 URL을 반환합니다

반환 된 URL은 사용자를 URL로 리디렉션하는 간단한 Jquery ajax 호출에 의해 수신됩니다.

이것은 사이트에서 매우 정기적으로 발생하며 현재 각 게시물에 대해 새로운 CFC 인스턴스가 생성됩니다. 대신 응용 프로그램 범위에 넣고 경쟁/잠금 조건을 발생시키지 않는 것이 안전합니까?

  • 답변 # 1

    파라미터를 전달해도 아무것도 "저장되지"않습니다. 개념적으로 각 스레드에는 자체 arguments 가 있습니다.  그리고 local  범위는 다른 스레드에 표시되지 않으며 함수가 종료되면 존재하지 않습니다. 따라서 이러한 관점에서 보면 충돌이 없습니다.

    또한 데이터를 저장한다고해서 데이터베이스 테이블에 저장하는 것은 아닙니다. 공유 범위/오브젝트 등에 데이터를 저장하여 상태를 유지하는 구성 요소를 나타냅니다. "공유"를 사용하면다른스레드에 리소스에 액세스 할 수 있으며 동시에 경쟁 조건으로 이어집니다.

    예를 들어, variables 에 정보를 "저장"하는이 (구성된) 구성 요소 함수를 사용하십시오.  범위. 매번 해당 구성 요소의 새 인스턴스를 작성하는 경우 각 요청이 자체 인스턴스와 별도의 variables 사본을 가져 오기 때문에 함수는 안전합니다.  재생할 범위.

    public numeric function doStuff( numeric num1, numeric num2 ) {
        variables.firstNum = arguments.num1 * 12;
        variables.secondNum = arguments.num2 * 10;
        return variables.firstNum / variables.secondNum;
     }
    
    

    이제 동일한 컴포넌트를 가져 와서 어플리케이션 범위에 넣으십시오. 더 이상 안전하지 않습니다. 당신이 application 에 저장하자마자  범위, 인스턴스-그리고 그 variables  -적용 범위도 넓습니다. 따라서 함수가 variables 에 데이터를 "저장"할 때  범위는 본질적으로 application 를 업데이트합니다  변하기 쉬운. 분명히모든요청에 액세스 할 수 있기 때문에 스레드로부터 안전하지 않습니다. 따라서 여러 스레드가 동일한 변수를 동시에 쉽게 읽고 수정하여 경쟁 조건을 초래할 수 있습니다.

    // "Essentially" becomes this .... 
    public numeric function doStuff( numeric num1, numeric num2 ) {
        application.firstNum = arguments.num1 * 12;
        application.secondNum = arguments.num2 * 10;
        return application.firstNum / application.secondNum;
    }
    
    

    James A Mohler가 지적했듯이 범위를 생략해도 동일한 문제가 발생합니다.범위없이 함수 변수를 선언해도 함수에 로컬 변수가되지 않습니다. 기본 범위 인 variables 의 일부입니다. -(위에서 설명한 것과 동일한 스레드 안전 문제 생성) 개발자가 단일 쿼리 변수 또는 루프 인덱스의 범위를 찾는 것을 잊었을 때 이러한 동작으로 인해 많은 스레딩 버그가 발생했습니다. 따라서 모든 함수 변수의 범위를 명시 적으로 지정해야합니다.

    // Implicitly creates "variables.firstNum" and "variables.secondNum"
     public numeric function doStuff( numeric num1, numeric num2 ) {
        firstNum = arguments.num1 * 12;
        secondNum = arguments.num2 * 10;
        return firstNum / secondNum;
     }
    
    

    잠금을 추가하는 것 외에도 local 를 사용하여명시 적으로스레드를 안전하게 만들 수 있습니다.  대신 범위. 일시적인 데이터를 local 에 저장함으로써  범위는 다른 스레드에 표시되지 않으며 함수가 종료되면 존재하지 않습니다.

    public numeric function doStuff( numeric num1, numeric num2 ) {
        local.firstNum = arguments.num1 * 12;
        local.secondNum = arguments.num2 * 10;
        return local.firstNum / local.secondNum;
     }
    
    

    물론 참조로 전달되는 복잡한 객체 나 구조, 함수 내에서 객체가 수정되는지 여부와 같은 다른 경우도 고려해야합니다. 그러나 "데이터 저장"의 의미와 스코핑이 stateless구성 요소 ( application 에 안전) 사이의 차이를 만드는 방법에 대한 정보를 얻을 수 있기를 바랍니다.  scope) 및 stateful구성 요소 (이 아닌)

    TL;DR;

    귀하의 경우 대부분의 정보가 공유되지 않고 요청 수준 (사용자 정보, 업로드 된 이미지 등) 인 것처럼 들리므로 응용 프로그램 범위에 저장하는 것이 안전합니다.

  • 이전 smarty - PrestaShop에서 themeyml 업데이트
  • 다음 python - 문자열 형식을 사용하여 숫자를 형식화하지만 값을 변경하지 마십시오