2013-04-06 21 views
7

Trước đây tôi đã hỏi một câu hỏi về phạm vi cf trên các trang cfm (vui vì tôi hiểu phạm vi CFC và các vấn đề tiềm ẩn), nhưng vẫn chưa rõ về phạm vi biến.coldfusion CFM Biến phạm vi

Trong câu trả lời cho câu hỏi trước của tôi, không có vấn đề về an toàn chủ đề khi sử dụng trang cfm và bạn sẽ không nhận được trường hợp hai người dùng khác truy cập vào cùng một trang và có điều kiện chủng tộc hoặc chủ đề an toàn chủ đề (ngay cả khi tôi chỉ để các biến của tôi trong phạm vi biến cfm mặc định và phạm vi biến cho mỗi người dùng sẽ bị cô lập và độc lập (đây là câu hỏi cuối cùng của tôi Coldfusion Scopes Clarification)

Tuy nhiên, tôi đã đọc bài đăng trên blog này http://blog.alexkyprianou.com/2010/09/20/variables-scope-in-coldfusion/ liên quan đến việc sử dụng các chức năng trên trang cfm và sử dụng phạm vi biến và dường như đề xuất một kịch bản theo đó phạm vi biến được chia sẻ giữa nhiều người dùng (tôi hiểu vấn đề này trong ngữ cảnh của CFC) n đến các lớp java và biến phạm vi là các biến mẫu, do đó, có các vấn đề an toàn luồng nếu CFC được chia sẻ/phạm vi ứng dụng/singleton) nhưng điều này dường như phản đối các câu trả lời trước đó - nếu biến được đặt trong phạm vi biến bởi hàm trên cfm trang có thể được truy cập bởi người dùng khác, sau đó chắc chắn biến được đặt trong phạm vi biến trực tiếp trong mã trang cfm là như nhau?

Tôi đã hy vọng một số tài liệu và hướng dẫn rõ ràng nhưng chưa thực sự có thể tìm thấy giải thích dứt khoát về các phạm vi khác nhau và nơi chúng có sẵn.

Cảm ơn!

+0

Vì phạm vi biến không phải là phạm vi chia sẻ nên không có vấn đề gì khi hai người dùng có thể tạo điều kiện chủng tộc, tuy nhiên, điều kiện chủng tộc có thể xảy ra với một người dùng. – BKK

+0

Hoạt động không đồng bộ sang một bên, làm thế nào có thể có một điều kiện chủng tộc? Chắc chắn khi một người dùng truy cập vào một trang của nó được thực hiện trong một chuỗi duy nhất, tuần tự thời trang? (Tôi đánh giá cao mặc dù rằng nếu bạn không biến phạm vi địa phương trong các chức năng nó có thể gây nhầm lẫn với việc sử dụng lại các tên biến và không nhận ra những điều đã được khởi tạo). Ngoài ra, bạn có nói rằng bài đăng blog không chính xác? – rhinds

+0

Trong bài đăng trên blog, anh đề cập đến "request1" và "request2", anh ấy có nói rõ ràng 2 người dùng khác nhau không? Tôi đã không nhận được ấn tượng đó, tôi đã đoán một số loại vấn đề đồng thời đa lõi. – BKK

Trả lời

12

Dan là chính xác và bài viết trên blog được tham chiếu trong câu hỏi đơn giản là sai. Mã của Dan thể hiện nó, và tôi có written-up and tested this thoroughly on my blog (nó quá lớn để đến đây).

Dòng dưới cùng là phạm vi biến trong CFM là an toàn từ loại điều kiện chủng tộc này vì phạm vi biến cho mỗi yêu cầu là bộ nhớ khác nhau. Vì vậy, một variables.foo không giống với variables.foo khác, vì vậy không bao giờ giao nhau. Điều này cũng áp dụng cho các đối tượng trong phạm vi biến: phạm vi biến nội bộ của chúng là một thực thể riêng biệt, vì vậy bất kỳ số yêu cầu nào cũng có thể khởi tạo CFC trong phạm vi biến của yêu cầu và phạm vi biến của các biến thể của CFC là tất cả các thực thể rời rạc .

Thời gian duy nhất phạm vi biến có thể tham gia vào điều kiện chủng tộc là phạm vi biến của một đối tượng được lưu trữ trong phạm vi được chia sẻ. Bởi vì tất cả các tham chiếu đến đối tượng chia sẻ phạm vi đó sẽ tham chiếu cùng một đối tượng trong bộ nhớ, do đó cùng phạm vi biến của đối tượng trong bộ nhớ.

3

Tôi nghĩ blog là gây hiểu lầm. Tuy nhiên, nếu bạn muốn tự mình xem, hãy viết một trang có chức năng của mình. Làm cho nó trông như thế này

<cffunction name="test" returntype="void"> 
<cfscript> 
foo = now(); 
sleep(3 * 60 * 1000); // should be 3 minutes 
writedump(foo); 
</cfscript> 
<cffunction> 

<cfdump var="#now()#"> 
<cfset test()> 

Chạy trang. Trong 3 phút, mở một trình duyệt hoặc tab khác và chạy lại. Quay trở lại nơi bạn lần đầu tiên chạy nó và chờ kết quả. Nếu không có sự khác biệt đáng kể giữa hai kết quả đầu ra, thì yêu cầu trang thứ hai của bạn không ảnh hưởng đến kết quả đầu tiên của bạn.

Lưu ý rằng tôi chưa tự mình thử nhưng đặt cược của tôi sẽ là yêu cầu thứ 2 không ảnh hưởng đến yêu cầu đầu tiên.

4

Chức năng bên ngoài CFC truy cập phạm vi biến sẽ không có vấn đề an toàn luồng khi 2 yêu cầu chạy mã, nhưng nếu bạn sử dụng tính năng cfthread hoặc song song khác, bạn vẫn có thể gặp sự cố với phạm vi biến được thay đổi và có thể gây ra điều kiện chủng tộc.Thường thì lỗi này có thể xảy ra với một biến mà bạn sử dụng nhiều như trong vòng lặp for, biến "i".

cho (i = 1; i < 10; i ++) {t = arr [i]; }

Nhưng sau đó chức năng khác thực hiện điều này trong khi người đầu tiên đang chạy:

for (i = 1; i < 20; i ++) {t = arr [i]; }

Biến "i" cần trở thành biến cục bộ để giúp làm cho chuỗi an toàn. Bạn không muốn vòng lặp đầu tiên có thể vượt quá 10 lỗi và điều này rất khó để gỡ lỗi nhiều lần. Tôi đã phải sửa một tấn các biến "i" và các biến khác để làm cho các hàm của tôi an toàn ở khắp mọi nơi khi tôi bắt đầu lưu vào bộ nhớ đệm các đối tượng và sử dụng cfthread rộng rãi hơn.

Bạn cũng có thể tránh phải khóa bằng cách không bao giờ thay đổi các đối tượng hiện có. Thay vào đó, bạn có thể làm việc trên các bản sao của chúng. Điều này làm cho dữ liệu "bất biến". CFML không có hỗ trợ chính thức để làm cho các đối tượng bất biến hiệu quả hơn, nhưng bạn có thể tạo bản sao dễ dàng. http://en.wikipedia.org/wiki/Immutable_object

dụ đơn giản của chủ đề thay đổi an toàn để một biến phạm vi ứng dụng:

var temp=structnew(); 
// build complete object 
temp.myValue=true; 
// set complete object to application scope variable 
application.myObject=temp; 

Viết cho bất kỳ đối tượng chia sẻ thường là nguy hiểm từ biến có thể được undefined hoặc xây dựng một phần. Tôi luôn luôn xây dựng đối tượng hoàn chỉnh và đặt nó vào biến được chia sẻ ở cuối như ví dụ trên. Điều này làm cho an toàn thread dễ dàng nếu nó không phải là quá đắt để tái tạo dữ liệu. Phạm vi biến trong CFC tương tự như biến thành viên riêng tư trong các ngôn ngữ khác. Nếu bạn sửa đổi dữ liệu trong các đối tượng được chia sẻ, bạn có thể sử dụng CFLOCK nếu bạn không thể tạo bản sao thay thế.

Một số sự nhầm lẫn về phạm vi coldfusion có liên quan đến phạm vi được chia sẻ trong coldfusion 5 và trước đó ít đáng tin cậy hơn. Họ có vấn đề an toàn chủ đề nghiêm trọng có thể gây ra sự cố hoặc hỏng dữ liệu. Hai luồng trong một số điều kiện nhất định có thể ghi vào cùng một bộ nhớ cùng một lúc nếu bạn không khóa chính xác. Các công cụ CFML hiện tại có thể ghi vào các khóa cấu trúc mà không có khả năng hỏng/hỏng. Bạn không thể chắc chắn dữ liệu nào sẽ thực sự kết thúc dưới dạng giá trị mà không cân nhắc đến sự an toàn của luồng, nhưng thường sẽ không bị hỏng trừ khi bạn đang xử lý các loại đối tượng không phải cfml như CFX, Java và các loại khác . Một lỗi an toàn thread vẫn có thể dẫn đến một vòng lặp vô hạn mà có thể treo yêu cầu cho đến khi nó hết giờ, nhưng nó sẽ không sụp đổ trừ khi nó hết bộ nhớ.

+0

@rhinds - Lưu ý rằng không thể bản địa hóa các biến chức năng có thể gây ra sự cố ngay cả trong một chuỗi đơn lẻ như [ví dụ này] (http://daveshuck.com/2006/11/28/thread-safety-example-var-scope- your-loop-index-in-coldfusion-cfcs /) minh họa. Trong khi nó sử dụng cfc, bạn sẽ nhận được kết quả tương tự nếu các hàm được đặt trong trang .cfm. Không phải là một điều kiện chủng tộc, nhưng nó minh họa tầm quan trọng của việc địa phương hóa các biến chức năng - luôn luôn. – Leigh

+1

Tôi muốn đề cập đến công cụ Railo cfml (getrailo.org) có tùy chọn "chế độ phạm vi cục bộ" trong trang quản trị - phạm vi có thể được đặt thành "luôn luôn" sẽ làm cho tất cả các biến chưa được sửa cục bộ thay vì phạm vi biến. Railo 4.1 cũng sẽ hỗ trợ tùy chọn này cho các chức năng riêng lẻ. Điều này làm cho việc chuyển đổi sang mã an toàn luồng nhanh hơn nếu bạn định di chuyển sang hành vi vượt trội của IMO này. Sử dụng các biến phạm vi theo mặc định là mã xấu trong một hàm hoặc CFC. –