Chương 2 : Phát biểu <flow> và vấn đề bế tắc
2.1. Phát biểu <flow>
2.1.1 Giới thiệu chung về <flow>
Tính đồng bộ và đồng thời thể hiện trong BPEL được cung cấp bởi cấu trúc luồng
<flow>. Cú pháp chung của <flow> biểu diễn như:
<flow standard-attributes> standard-elements <links>? <link name="NCName">+ </links> activity+ </flow>
Mục đích của <flow> cơ bản là nhóm một tập các thành phần bên trong, trong bao đóng của nó để thực thi đồng thời, một <flow> hoàn thành khi tất cả các thành phần nằm trong nó đã được hoàn thành. Nếu điều kiện trả về giá trị false thì một thành phần bị ngừng và cũng được xem hoàn thành (Dead-Path-Elimination).
<sequence> <flow>
<invoke partnerLink="Seller" ... /> <invoke partnerLink="Shipper" ... /> </flow>
<invoke partnerLink="Bank" name="transferMoney" ... />
</sequence>
Ở ví dụ trên, hai thành phần <invoke> khởi tạo để đồng thời bắt đầu khi <flow>
bắt đầu. Giả sử phương thức hoạt động <invoke> là phương thức yêu cầu – phản hồi, <flow> hoàn thành ngay sau khi cả phương thức seller và shipper trả lời. Và thành phần transferMoney thực thi sau khi <flow> hoàn thành.
Thành phần <flow> nhóm một tập các thành phần thực thi đồng thời nằm trực tiếp trong nó. Gồm có các phụ thuộc đồng bộ hóa giữa các thành phần nằm trong nó với bất kỳ độ sâu nào. <link> được dùng để diễn giải các phụ thuộc đồng bộ hóa đó.
2.1.2 Các thành phần và thuộc tính chuẩn liên quan <flow>
Các thuộc tính chuẩn (standard-attributes) và các thành phần chuẩn (standard- elements) của các thành phần con nằm bên trong một <flow> có ý nghĩa quan trọng bởi vì các thành phần và thuộc tính chuẩn tồn tại để cung cấp các ngữ nghĩa liên kết giữa các thành phần hoạt động với nhau. Mỗi thành phần <flow> của BPEL có thành phần quản lý khai báo <sources> và <targets>, chứa tập hợp của các thành phần
<source> và <target> tương ứng. Các thành phần đó được sử dụng để thiết lập
các mối quan hệ đồng bộ qua một <link>.
<targets>? <joinCondition expressionLanguage="anyURI"?>? bool-expr </joinCondition> <target linkName="NCName" />+ </targets> <sources>? <source linkName="NCName">+ <transitionCondition expressionLanguage="anyURI"?>? bool-expr </transitionCondition> </source> </sources>
Giá trị của thuộc tính linkName của <source> và <target> phải là name của
một <link> được khai báo trong một <flow> bao nó. Một thành phần khai báo
chính nó là nguồn của một hoặc nhiều liên kết bao gồm một hoặc nhiều thành phần
<source>. Mỗi thành phần <source> được kết hợp cùng một thành phần hoạt
động khác đưa ra phải sử dụng một linkName không trùng từ tất cả các thành phần
<source> của activity đó. Hai <links> khác nhau phải không chia sẻ cùng các
thành phần hoạt động cùng nguồn và đích, đó là, tại một link được sử dụng để kết nối hai activities. Mọi link được khai báo bên trong một <flow> phải có chính xác một activity bên trong <flow> đó như nguồn của nó và chính xác một activity bên trong
<flow> là đích của nó. Nguồn và đích của một link có thể lồng với độ sâu tùy ý bên trong các activities có cấu trúc lồng trong <flow>.
Các <targets>, đặc tả một <joinCodition> tùy chọn. Giá trị của thành phần
<joinCondition> là một biểu thức Boolean trong ngôn ngữ biểu thức đưa ra bởi
thuộc tính expressionLanguage, hoặc trong ngôn ngữ biểu thức mặc định cho tiến trình đó. Nếu không <joinCondition> được đặc tả, <joinCondition>
(như toán tử OR) tách biệt của trạng thái link của tất cả các link đi ra của activity đó. Mỗi thành phần <source> đặc tả một <transitionCondition> tùy chọn như một sự bảo vệ đối với link đặc biệt. Nếu <transitionCondition> bị bỏ qua, nó được giả lập tới giá trị true.
Một trong các thuộc tính chuẩn (standard-attribute) tùy chọn trên mọi activity,
suppressJoinFailure, có liên quan tới các links. Thuộc tính đó đòi hỏi bất cứ
khi nào một lỗi bpel:joinFailure bị ném ra ngoại lệ nếu chương trình có lỗi. Khi thuộc tính suppressJoinFailure không được đặc tả cho một activity, nó thừa kế giá trị của nó từ cấu trúc bao nó.
Một link có nguồn <source> lồng bên trong cấu trúc ngữ pháp, tại bất kỳ mức nào, thì link đó không được khai báo bên trong cấu trúc đó tại bất cứ mức nào. Có nghĩa rằng một link rời khỏi (leaving) cấu trúc đó. Cũng được xem, một link mà đích
<target> lồng bên trong một cấu trúc chuẩn pháp tại bất cứ mức nào, thì link đó
không được khai báo bên trong cấu trúc đó tại bất kỳ mức nào. Tương ứng một link đi vào (entering) cấu trúc đó. Một link đi vào hoặc rời khỏi một cấu trúc sẽ vượt qua ranh giới của cấu trúc định nghĩa.
Một link được sử dụng bên trong một cấu trúc lặp ( <while>, <repeatUntil>,
<forEach>, <eventHandlers>) hoặc một <compensationHandler> phải
được khai báo trong một <flow> mà chính nó lồng bên trong cấu trúc lặp hoặc
<compensationHandler>. Một link phải không được vượt qua ranh giới của một
cấu trúc lặp hoặc thành phần <compensationHandler>. Và nếu link nào vượt qua một thành phần biên <catch>, <catchall> hoặc thành phần điều khiển ngắt
<terminationHandler> ngoại biên, thì nó phải có thành phần nguồn bên trong
<faultHandlers> hoặc <terminationHandler>, và thành phần đích bên
ngoài của phạm vi kết hợp với trình điều khiển. Một <link> được khai báo trong một
<flow> phải không tạo một vòng điều khiển, đó là, activity nguồn phải không là
activity đích xem như một activity trước nó. Ngụ ý rằng đồ thị trực tiếp luôn luôn không là mạch hở. Activity A được nối tới activity B trước nó về mặt logic nếu khởi tạo của B về mặt ngữ pháp yêu cầu sự hoàn thành của A. Nói riêng, một link phải không có một activity như là đích nếu activity nguồn kèm activity đích hoặc ngược lại.
2.1.3 Thành phần <link> trong <flow>
Trạng thái link là một cờ ba trạng thái được kết hợp cùng mỗi <link> đã khai báo, gồm true, false hoặc unset. Vòng đời của trạng thái của một <link> chính xác là vòng đời của activity <flow> bên trong chính nó được khai báo tới. Một activity
<flow> kích hoạt, trạng thái của tất cả các links được khai báo trong activity đó là
unset. Nếu một activity đã sẵn sàng để bắt đầu tương ứng các links đi vào, thì nó phải không bắt đầu cho đến khi trạng thái của tất cả của các links đi vào nó được xác định và điều kiện nối ngầm định hoặc rõ ràng cũng phải được định giá trị. Trên sắp xếp để tránh các sự phụ thuộc điều khiển vi phạm, các định giá của điều kiện nối được thực thi chỉ sau trạng thái của tất cả các links đi vào đã được xác định. Để hiểu rõ hơn về trạng thái định giá của link, hãy xem ví dụ mô tả sau. Khi activity A hoàn thành mà không truyền bất cứ sai lầm nào, các bước tiếp theo phải được thực hiện để xác định hiệu quả của các links trên các activities khác:
Bước 1: Xác định trạng thái của tất cả các links đi vào cho A. Trạng thái sẽ là true hoặc false. Để xác định trạng thái của mỗi link trong một <flow> thì điều kiện dịch chuyển <tranditionCondition> của nó phải được định giá.
Bước 2: Với mỗi activity B mà có một sự phụ thuộc đồng bộ trong A, kiểm tra xem: Bước 2.1: B đã sẵn sàng để bắt đầu (phụ thuộc trong các link đi vào).
Bước 2.2: Trạng thái của tất cả các links đi vào với B đã được xác định.
Bước 3: Nếu các điều kiện trên là true, thì định giá <joinCondition> cho B, nếu nó định giá tới true, activity B được bắt đầu. Còn không một lỗi sai chuẩn
bpel:joinFailure phải được ném ra, nhưng khi giá trị của thuộc tính
suppressJoinFailure là yes trong trường hợp bpel:joinFailure không
được ném.
Khi một activity có nhiều link đi vào, sự sắp xếp trong chúng, trạng thái của các link và các điều kiện dịch chuyển kết hợp được định nghĩa tới tính tuần tự, theo sắp đặt của các links khai báo trong thành phần nguồn <source>. Thành phần nguồn liên quan phải hoàn thành trước điều kiện <transitionCondition> của một link được định giá. Nếu một lỗi xuất hiện trong quá trình định giá điều kiện dịch chuyển
<transitionCondition> của một của các link đi vào của một activity, thì tất cả
các link đi vào còn lại cùng với các đích bên trong phạm vi bao đóng của activity nguồn phải không có các điều kiện dịch chuyển của chúng được định giá và còn lại ở trạng thái unset. Tuy nhiên, nếu đích của một link đi vào còn lại là bên ngoài phạm vi bao đóng của activity nguồn thì trạng thái của link phải cài đặt tới false.
2.1.4 Ví dụ về <flow>
Trong ví dụ sau, các activities cùng các tên receiveBuyerInformation,
receiveSellerInformation, settleTrade, confirmBuyer, và
confirmSeller là một nút trong đồ thị định nghĩa một activity <flow>.
Hình 2.1: Ví dụ về luồng Flow
Hoạt động <flow> sau được định nghĩa:
- buyToSettle là link bắt đầu tại receiveBuyerInformation (được đặc
tả trong thành phần nguồn <source> tương ứng được lồng trong thành phần
receiveBuyerInformation) và kết thúc tại settleTrade (được đặc tả trong
thành phần <target> tương ứng được lồng trong settleTrade).
- sellToSettle là link bắt đầu tại receiveSellerInformation và kết
thúc tại settleTrade.
- toBuyConfirm bắt đầu tại settleTrade và kết thúc tại confirmBuyer.
- toSellConfirm là link bắt đầu từ thành phần settleTrade và kết thúc
tại confirmSeller.
Dựa trên cấu trúc đồ thị được định nghĩa bởi <flow>, thành phần biểu diễn cho
thi đồng thời. Activity settleTrade được thực thi chỉ sau cả hai activities trên đã hoàn thành. Sau settleTrade hoàn thành hai activities confirmBuyer và
confirmSeller được hoàn thành đồng thời nữa.