BPM ಶೈಲಿಯ ಏಕೀಕರಣ

BPM ಶೈಲಿಯ ಏಕೀಕರಣ

ಹಾಯ್ ಹಬ್ರ್!

ನಮ್ಮ ಕಂಪನಿಯು ಇಆರ್‌ಪಿ-ವರ್ಗದ ಸಾಫ್ಟ್‌ವೇರ್ ಪರಿಹಾರಗಳ ಅಭಿವೃದ್ಧಿಯಲ್ಲಿ ಪರಿಣತಿಯನ್ನು ಹೊಂದಿದೆ, ಅದರಲ್ಲಿ ಸಿಂಹದ ಪಾಲನ್ನು ವ್ಯವಹಾರದ ವ್ಯವಸ್ಥೆಗಳು ಬೃಹತ್ ಪ್ರಮಾಣದ ವ್ಯವಹಾರ ತರ್ಕ ಮತ್ತು ಡಾಕ್ಯುಮೆಂಟ್ ಹರಿವು ಎ ಲಾ ಇಡಿಎಂಎಸ್‌ನೊಂದಿಗೆ ಆಕ್ರಮಿಸಿಕೊಂಡಿವೆ. ನಮ್ಮ ಉತ್ಪನ್ನಗಳ ಪ್ರಸ್ತುತ ಆವೃತ್ತಿಗಳು JavaEE ತಂತ್ರಜ್ಞಾನಗಳನ್ನು ಆಧರಿಸಿವೆ, ಆದರೆ ನಾವು ಸೂಕ್ಷ್ಮ ಸೇವೆಗಳೊಂದಿಗೆ ಸಕ್ರಿಯವಾಗಿ ಪ್ರಯೋಗಿಸುತ್ತಿದ್ದೇವೆ. ಅಂತಹ ಪರಿಹಾರಗಳ ಅತ್ಯಂತ ಸಮಸ್ಯಾತ್ಮಕ ಕ್ಷೇತ್ರಗಳಲ್ಲಿ ಒಂದಾದ ಪಕ್ಕದ ಡೊಮೇನ್‌ಗಳಿಗೆ ಸೇರಿದ ವಿವಿಧ ಉಪವ್ಯವಸ್ಥೆಗಳ ಏಕೀಕರಣವಾಗಿದೆ. ನಾವು ಬಳಸುವ ವಾಸ್ತುಶಿಲ್ಪದ ಶೈಲಿಗಳು, ತಂತ್ರಜ್ಞಾನದ ಸ್ಟ್ಯಾಕ್‌ಗಳು ಮತ್ತು ಚೌಕಟ್ಟುಗಳನ್ನು ಲೆಕ್ಕಿಸದೆ ಏಕೀಕರಣ ಸಮಸ್ಯೆಗಳು ಯಾವಾಗಲೂ ನಮಗೆ ದೊಡ್ಡ ತಲೆನೋವನ್ನು ನೀಡುತ್ತವೆ, ಆದರೆ ಇತ್ತೀಚೆಗೆ ಅಂತಹ ಸಮಸ್ಯೆಗಳನ್ನು ಪರಿಹರಿಸುವಲ್ಲಿ ಪ್ರಗತಿ ಕಂಡುಬಂದಿದೆ.

ಲೇಖನದಲ್ಲಿ ನಾನು ನಿಮ್ಮ ಗಮನಕ್ಕೆ ತರುತ್ತೇನೆ, ಗೊತ್ತುಪಡಿಸಿದ ಪ್ರದೇಶದಲ್ಲಿ NPO ಕ್ರಿಸ್ಟಾ ಹೊಂದಿರುವ ಅನುಭವ ಮತ್ತು ವಾಸ್ತುಶಿಲ್ಪದ ಸಂಶೋಧನೆಯ ಬಗ್ಗೆ ನಾನು ಮಾತನಾಡುತ್ತೇನೆ. ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್‌ನ ದೃಷ್ಟಿಕೋನದಿಂದ ಏಕೀಕರಣ ಸಮಸ್ಯೆಗೆ ಸರಳ ಪರಿಹಾರದ ಉದಾಹರಣೆಯನ್ನು ನಾವು ನೋಡುತ್ತೇವೆ ಮತ್ತು ಈ ಸರಳತೆಯ ಹಿಂದೆ ಏನನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ ಎಂಬುದನ್ನು ಕಂಡುಹಿಡಿಯುತ್ತೇವೆ.

ಹಕ್ಕು ನಿರಾಕರಣೆ

ಲೇಖನದಲ್ಲಿ ವಿವರಿಸಿದ ವಾಸ್ತುಶಿಲ್ಪ ಮತ್ತು ತಾಂತ್ರಿಕ ಪರಿಹಾರಗಳನ್ನು ನಿರ್ದಿಷ್ಟ ಕಾರ್ಯಗಳ ಸಂದರ್ಭದಲ್ಲಿ ವೈಯಕ್ತಿಕ ಅನುಭವದ ಆಧಾರದ ಮೇಲೆ ನನ್ನಿಂದ ಪ್ರಸ್ತಾಪಿಸಲಾಗಿದೆ. ಈ ಪರಿಹಾರಗಳು ಸಾರ್ವತ್ರಿಕವೆಂದು ಹೇಳಿಕೊಳ್ಳುವುದಿಲ್ಲ ಮತ್ತು ಬಳಕೆಯ ಇತರ ಪರಿಸ್ಥಿತಿಗಳಲ್ಲಿ ಸೂಕ್ತವಾಗಿರುವುದಿಲ್ಲ.

ಬಿಪಿಎಂಗೂ ಇದಕ್ಕೂ ಏನು ಸಂಬಂಧ?

ಈ ಪ್ರಶ್ನೆಗೆ ಉತ್ತರಿಸಲು, ನಮ್ಮ ಪರಿಹಾರಗಳ ಅನ್ವಯಿಕ ಸಮಸ್ಯೆಗಳ ನಿಶ್ಚಿತಗಳನ್ನು ನಾವು ಸ್ವಲ್ಪ ಆಳವಾಗಿ ಪರಿಶೀಲಿಸಬೇಕಾಗಿದೆ. ನಮ್ಮ ವಿಶಿಷ್ಟ ವಹಿವಾಟು ವ್ಯವಸ್ಥೆಯಲ್ಲಿನ ವ್ಯವಹಾರ ತರ್ಕದ ಮುಖ್ಯ ಭಾಗವೆಂದರೆ ಬಳಕೆದಾರ ಇಂಟರ್ಫೇಸ್‌ಗಳ ಮೂಲಕ ಡೇಟಾಬೇಸ್‌ಗೆ ಡೇಟಾವನ್ನು ನಮೂದಿಸುವುದು, ಈ ಡೇಟಾದ ಹಸ್ತಚಾಲಿತ ಮತ್ತು ಸ್ವಯಂಚಾಲಿತ ಪರಿಶೀಲನೆ, ಕೆಲವು ವರ್ಕ್‌ಫ್ಲೋ ಮೂಲಕ ಅದನ್ನು ನಿರ್ವಹಿಸುವುದು, ಅದನ್ನು ಮತ್ತೊಂದು ಸಿಸ್ಟಮ್ / ವಿಶ್ಲೇಷಣಾತ್ಮಕ ಡೇಟಾಬೇಸ್ / ಆರ್ಕೈವ್‌ಗೆ ಪ್ರಕಟಿಸುವುದು, ವರದಿಗಳನ್ನು ರಚಿಸುವುದು . ಹೀಗಾಗಿ, ಗ್ರಾಹಕರಿಗೆ ಸಿಸ್ಟಮ್ನ ಪ್ರಮುಖ ಕಾರ್ಯವೆಂದರೆ ಅವರ ಆಂತರಿಕ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳ ಯಾಂತ್ರೀಕರಣವಾಗಿದೆ.

ಅನುಕೂಲಕ್ಕಾಗಿ, ನಾವು ಸಂವಹನದಲ್ಲಿ "ಡಾಕ್ಯುಮೆಂಟ್" ಎಂಬ ಪದವನ್ನು ಒಂದು ನಿರ್ದಿಷ್ಟ ವರ್ಕ್‌ಫ್ಲೋ ಅನ್ನು "ಲಿಂಕ್" ಮಾಡಬಹುದಾದ ಸಾಮಾನ್ಯ ಕೀಲಿಯಿಂದ ಸಂಯೋಜಿಸಲಾದ ಡೇಟಾದ ಕೆಲವು ಅಮೂರ್ತತೆಯಾಗಿ ಬಳಸುತ್ತೇವೆ.
ಆದರೆ ಏಕೀಕರಣ ತರ್ಕದ ಬಗ್ಗೆ ಏನು? ಎಲ್ಲಾ ನಂತರ, ಏಕೀಕರಣ ಕಾರ್ಯವು ಸಿಸ್ಟಮ್ನ ವಾಸ್ತುಶಿಲ್ಪದಿಂದ ಉತ್ಪತ್ತಿಯಾಗುತ್ತದೆ, ಇದು ಗ್ರಾಹಕರ ಕೋರಿಕೆಯ ಮೇರೆಗೆ ಭಾಗಗಳಾಗಿ "ಕತ್ತರಿಸಲಾಗುತ್ತದೆ", ಆದರೆ ಸಂಪೂರ್ಣವಾಗಿ ವಿಭಿನ್ನ ಅಂಶಗಳ ಪ್ರಭಾವದ ಅಡಿಯಲ್ಲಿ:

  • ಕಾನ್ವೇ ಕಾನೂನಿಗೆ ಒಳಪಟ್ಟಿರುತ್ತದೆ;
  • ಇತರ ಉತ್ಪನ್ನಗಳಿಗೆ ಹಿಂದೆ ಅಭಿವೃದ್ಧಿಪಡಿಸಿದ ಉಪವ್ಯವಸ್ಥೆಗಳನ್ನು ಮರುಬಳಕೆ ಮಾಡುವ ಪರಿಣಾಮವಾಗಿ;
  • ವಾಸ್ತುಶಿಲ್ಪಿ ವಿವೇಚನೆಯಿಂದ, ಕ್ರಿಯಾತ್ಮಕವಲ್ಲದ ಅಗತ್ಯತೆಗಳ ಆಧಾರದ ಮೇಲೆ.

ಏಕೀಕರಣ ಕಲಾಕೃತಿಗಳೊಂದಿಗೆ ವ್ಯಾಪಾರ ತರ್ಕವನ್ನು ಕಲುಷಿತಗೊಳಿಸದಂತೆ ಮತ್ತು ಸಿಸ್ಟಮ್ನ ವಾಸ್ತುಶಿಲ್ಪದ ಭೂದೃಶ್ಯದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಪರಿಶೀಲಿಸುವ ಅಗತ್ಯದಿಂದ ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್ ಅನ್ನು ಉಳಿಸದಂತೆ, ಮುಖ್ಯ ಕೆಲಸದ ಹರಿವಿನ ವ್ಯವಹಾರ ತರ್ಕದಿಂದ ಏಕೀಕರಣ ತರ್ಕವನ್ನು ಪ್ರತ್ಯೇಕಿಸಲು ಒಂದು ದೊಡ್ಡ ಪ್ರಲೋಭನೆ ಇದೆ. ಈ ವಿಧಾನವು ಹಲವಾರು ಪ್ರಯೋಜನಗಳನ್ನು ಹೊಂದಿದೆ, ಆದರೆ ಅಭ್ಯಾಸವು ಅದರ ನಿಷ್ಪರಿಣಾಮವನ್ನು ತೋರಿಸುತ್ತದೆ:

  • ಏಕೀಕರಣದ ಸಮಸ್ಯೆಗಳನ್ನು ಪರಿಹರಿಸುವುದು ಸಾಮಾನ್ಯವಾಗಿ ಸಿಂಕ್ರೊನಸ್ ಕರೆಗಳ ರೂಪದಲ್ಲಿ ಸರಳವಾದ ಆಯ್ಕೆಗಳಿಗೆ ಮರಳುತ್ತದೆ ಏಕೆಂದರೆ ಮುಖ್ಯ ಕೆಲಸದ ಹರಿವಿನ ಅನುಷ್ಠಾನದಲ್ಲಿನ ಸೀಮಿತ ವಿಸ್ತರಣೆಯ ಬಿಂದುಗಳು (ಸಿಂಕ್ರೊನಸ್ ಏಕೀಕರಣದ ಅನಾನುಕೂಲಗಳನ್ನು ಕೆಳಗೆ ಚರ್ಚಿಸಲಾಗಿದೆ);
  • ಮತ್ತೊಂದು ಉಪವ್ಯವಸ್ಥೆಯಿಂದ ಪ್ರತಿಕ್ರಿಯೆ ಅಗತ್ಯವಿರುವಾಗ ಏಕೀಕರಣ ಕಲಾಕೃತಿಗಳು ಇನ್ನೂ ಪ್ರಮುಖ ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಭೇದಿಸುತ್ತವೆ;
  • ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್ ಏಕೀಕರಣವನ್ನು ನಿರ್ಲಕ್ಷಿಸುತ್ತಾನೆ ಮತ್ತು ಕೆಲಸದ ಹರಿವನ್ನು ಬದಲಾಯಿಸುವ ಮೂಲಕ ಅದನ್ನು ಸುಲಭವಾಗಿ ಮುರಿಯಬಹುದು;
  • ಬಳಕೆದಾರರ ದೃಷ್ಟಿಕೋನದಿಂದ ಸಿಸ್ಟಮ್ ಒಂದೇ ಸಂಪೂರ್ಣವಾಗುವುದನ್ನು ನಿಲ್ಲಿಸುತ್ತದೆ, ಉಪವ್ಯವಸ್ಥೆಗಳ ನಡುವಿನ "ಸ್ತರಗಳು" ಗಮನಾರ್ಹವಾಗುತ್ತವೆ ಮತ್ತು ಅನಗತ್ಯ ಬಳಕೆದಾರ ಕಾರ್ಯಾಚರಣೆಗಳು ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತವೆ ಅದು ಒಂದು ಉಪವ್ಯವಸ್ಥೆಯಿಂದ ಇನ್ನೊಂದಕ್ಕೆ ಡೇಟಾವನ್ನು ವರ್ಗಾಯಿಸಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ.

ಮತ್ತೊಂದು ವಿಧಾನವೆಂದರೆ ಏಕೀಕರಣ ಸಂವಹನಗಳನ್ನು ಪ್ರಮುಖ ವ್ಯವಹಾರ ತರ್ಕ ಮತ್ತು ಕೆಲಸದ ಹರಿವಿನ ಅವಿಭಾಜ್ಯ ಭಾಗವಾಗಿ ಪರಿಗಣಿಸುವುದು. ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್ ಅರ್ಹತೆಗಳು ಗಗನಕ್ಕೇರುವುದನ್ನು ತಡೆಯಲು, ಹೊಸ ಏಕೀಕರಣ ಸಂವಹನಗಳನ್ನು ರಚಿಸುವುದು ಸುಲಭ ಮತ್ತು ಪ್ರಯತ್ನವಿಲ್ಲದಂತಿರಬೇಕು, ಪರಿಹಾರವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಕನಿಷ್ಠ ಅವಕಾಶವಿದೆ. ಇದು ತೋರುತ್ತಿರುವುದಕ್ಕಿಂತ ಇದನ್ನು ಮಾಡುವುದು ಕಷ್ಟ: "ಪಾದದಲ್ಲಿ ತನ್ನನ್ನು ತಾನು ಶೂಟ್ ಮಾಡಿಕೊಳ್ಳಲು" ಅನುಮತಿಸದೆ, ಅದರ ಬಳಕೆಗೆ ಅಗತ್ಯವಿರುವ ವಿವಿಧ ಆಯ್ಕೆಗಳನ್ನು ಬಳಕೆದಾರರಿಗೆ ಒದಗಿಸಲು ಉಪಕರಣವು ಸಾಕಷ್ಟು ಶಕ್ತಿಯುತವಾಗಿರಬೇಕು. ಇಂಜಿನಿಯರ್‌ಗಳು ಏಕೀಕರಣ ಕಾರ್ಯಗಳ ಸಂದರ್ಭದಲ್ಲಿ ಉತ್ತರಿಸಬೇಕಾದ ಹಲವು ಪ್ರಶ್ನೆಗಳಿವೆ, ಆದರೆ ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್ ತನ್ನ ದೈನಂದಿನ ಕೆಲಸದಲ್ಲಿ ಯೋಚಿಸಬಾರದು: ವಹಿವಾಟಿನ ಗಡಿಗಳು, ಸ್ಥಿರತೆ, ಪರಮಾಣು, ಭದ್ರತೆ, ಸ್ಕೇಲಿಂಗ್, ಲೋಡ್ ಮತ್ತು ಸಂಪನ್ಮೂಲ ವಿತರಣೆ, ರೂಟಿಂಗ್, ಮಾರ್ಷಲಿಂಗ್, ವಿತರಣೆ ಮತ್ತು ಸ್ವಿಚಿಂಗ್ ಸಂದರ್ಭಗಳು, ಇತ್ಯಾದಿ. ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್‌ಗಳಿಗೆ ಸಾಕಷ್ಟು ಸರಳವಾದ ಪರಿಹಾರ ಟೆಂಪ್ಲೇಟ್‌ಗಳನ್ನು ನೀಡುವುದು ಅವಶ್ಯಕ, ಇದರಲ್ಲಿ ಅಂತಹ ಎಲ್ಲಾ ಪ್ರಶ್ನೆಗಳಿಗೆ ಉತ್ತರಗಳನ್ನು ಈಗಾಗಲೇ ಮರೆಮಾಡಲಾಗಿದೆ. ಈ ಟೆಂಪ್ಲೆಟ್ಗಳು ಸಾಕಷ್ಟು ಸುರಕ್ಷಿತವಾಗಿರಬೇಕು: ವ್ಯವಹಾರ ತರ್ಕವು ಆಗಾಗ್ಗೆ ಬದಲಾಗುತ್ತದೆ, ಇದು ದೋಷಗಳನ್ನು ಪರಿಚಯಿಸುವ ಅಪಾಯವನ್ನು ಹೆಚ್ಚಿಸುತ್ತದೆ, ದೋಷಗಳ ವೆಚ್ಚವು ಸಾಕಷ್ಟು ಕಡಿಮೆ ಮಟ್ಟದಲ್ಲಿ ಉಳಿಯಬೇಕು.

ಆದರೆ ಬಿಪಿಎಂಗೂ ಇದಕ್ಕೂ ಏನು ಸಂಬಂಧ? ಕೆಲಸದ ಹರಿವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಹಲವು ಆಯ್ಕೆಗಳಿವೆ ...
ವಾಸ್ತವವಾಗಿ, ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳ ಮತ್ತೊಂದು ಅನುಷ್ಠಾನವು ನಮ್ಮ ಪರಿಹಾರಗಳಲ್ಲಿ ಬಹಳ ಜನಪ್ರಿಯವಾಗಿದೆ - ರಾಜ್ಯ ಪರಿವರ್ತನೆಯ ರೇಖಾಚಿತ್ರದ ಘೋಷಣಾತ್ಮಕ ವ್ಯಾಖ್ಯಾನ ಮತ್ತು ಪರಿವರ್ತನೆಗಳಿಗೆ ವ್ಯವಹಾರ ತರ್ಕದೊಂದಿಗೆ ಹ್ಯಾಂಡ್ಲರ್ಗಳ ಸಂಪರ್ಕದ ಮೂಲಕ. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿ "ಡಾಕ್ಯುಮೆಂಟ್" ನ ಪ್ರಸ್ತುತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸುವ ರಾಜ್ಯವು "ಡಾಕ್ಯುಮೆಂಟ್" ನ ಗುಣಲಕ್ಷಣವಾಗಿದೆ.

BPM ಶೈಲಿಯ ಏಕೀಕರಣ
ಯೋಜನೆಯ ಪ್ರಾರಂಭದಲ್ಲಿ ಪ್ರಕ್ರಿಯೆಯು ಈ ರೀತಿ ಕಾಣುತ್ತದೆ

ಈ ಅನುಷ್ಠಾನದ ಜನಪ್ರಿಯತೆಯು ರೇಖೀಯ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ರಚಿಸುವ ತುಲನಾತ್ಮಕ ಸರಳತೆ ಮತ್ತು ವೇಗದಿಂದಾಗಿ. ಆದಾಗ್ಯೂ, ಸಾಫ್ಟ್‌ವೇರ್ ವ್ಯವಸ್ಥೆಗಳು ನಿರಂತರವಾಗಿ ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾಗುತ್ತಿದ್ದಂತೆ, ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಸ್ವಯಂಚಾಲಿತ ಭಾಗವು ಬೆಳೆಯುತ್ತದೆ ಮತ್ತು ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾಗುತ್ತದೆ. ವಿಭಜನೆಯ ಅವಶ್ಯಕತೆಯಿದೆ, ಪ್ರಕ್ರಿಯೆಗಳ ಭಾಗಗಳ ಮರುಬಳಕೆ, ಹಾಗೆಯೇ ಕವಲೊಡೆಯುವ ಪ್ರಕ್ರಿಯೆಗಳು ಆದ್ದರಿಂದ ಪ್ರತಿ ಶಾಖೆಯನ್ನು ಸಮಾನಾಂತರವಾಗಿ ಕಾರ್ಯಗತಗೊಳಿಸಲಾಗುತ್ತದೆ. ಅಂತಹ ಪರಿಸ್ಥಿತಿಗಳಲ್ಲಿ, ಉಪಕರಣವು ಅನಾನುಕೂಲವಾಗುತ್ತದೆ ಮತ್ತು ರಾಜ್ಯ ಪರಿವರ್ತನೆಯ ರೇಖಾಚಿತ್ರವು ಅದರ ಮಾಹಿತಿ ವಿಷಯವನ್ನು ಕಳೆದುಕೊಳ್ಳುತ್ತದೆ (ಏಕೀಕರಣದ ಪರಸ್ಪರ ಕ್ರಿಯೆಗಳು ರೇಖಾಚಿತ್ರದಲ್ಲಿ ಪ್ರತಿಫಲಿಸುವುದಿಲ್ಲ).

BPM ಶೈಲಿಯ ಏಕೀಕರಣ
ಅವಶ್ಯಕತೆಗಳ ಸ್ಪಷ್ಟೀಕರಣದ ಹಲವಾರು ಪುನರಾವರ್ತನೆಗಳ ನಂತರ ಈ ಪ್ರಕ್ರಿಯೆಯು ಕಾಣುತ್ತದೆ.

ಈ ಪರಿಸ್ಥಿತಿಯಿಂದ ಹೊರಬರುವ ಮಾರ್ಗವೆಂದರೆ ಎಂಜಿನ್ನ ಏಕೀಕರಣ jBPM ಅತ್ಯಂತ ಸಂಕೀರ್ಣವಾದ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳೊಂದಿಗೆ ಕೆಲವು ಉತ್ಪನ್ನಗಳಾಗಿ. ಅಲ್ಪಾವಧಿಯಲ್ಲಿ, ಈ ಪರಿಹಾರವು ಸ್ವಲ್ಪ ಯಶಸ್ಸನ್ನು ಕಂಡಿತು: ಸಂಕೇತದಲ್ಲಿ ಸಾಕಷ್ಟು ತಿಳಿವಳಿಕೆ ಮತ್ತು ಸಂಬಂಧಿತ ರೇಖಾಚಿತ್ರವನ್ನು ನಿರ್ವಹಿಸುವಾಗ ಸಂಕೀರ್ಣ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಸಾಧ್ಯವಾಯಿತು. BPMN2.

BPM ಶೈಲಿಯ ಏಕೀಕರಣ
ಸಂಕೀರ್ಣ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಒಂದು ಸಣ್ಣ ಭಾಗ

ದೀರ್ಘಾವಧಿಯಲ್ಲಿ, ಪರಿಹಾರವು ನಿರೀಕ್ಷೆಗಳಿಗೆ ತಕ್ಕಂತೆ ಜೀವಿಸಲಿಲ್ಲ: ದೃಶ್ಯ ಸಾಧನಗಳ ಮೂಲಕ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ರಚಿಸುವ ಹೆಚ್ಚಿನ ಕಾರ್ಮಿಕ ತೀವ್ರತೆಯು ಸ್ವೀಕಾರಾರ್ಹ ಉತ್ಪಾದಕತೆಯ ಸೂಚಕಗಳನ್ನು ಸಾಧಿಸಲು ಅನುಮತಿಸಲಿಲ್ಲ, ಮತ್ತು ಉಪಕರಣವು ಡೆವಲಪರ್‌ಗಳಲ್ಲಿ ಹೆಚ್ಚು ಇಷ್ಟಪಡದಿರುವಿಕೆಗಳಲ್ಲಿ ಒಂದಾಗಿದೆ. ಇಂಜಿನ್ನ ಆಂತರಿಕ ರಚನೆಯ ಬಗ್ಗೆ ದೂರುಗಳೂ ಇದ್ದವು, ಇದು ಅನೇಕ "ಪ್ಯಾಚ್ಗಳು" ಮತ್ತು "ಊರುಗೋಲುಗಳು" ಕಾಣಿಸಿಕೊಳ್ಳಲು ಕಾರಣವಾಯಿತು.

ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಯ ನಿದರ್ಶನದ ಸ್ವಂತ ನಿರಂತರ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿರುವ ಪ್ರಯೋಜನಗಳು ಮತ್ತು ಹಾನಿಗಳ ಅರಿವು jBPM ಅನ್ನು ಬಳಸುವ ಪ್ರಮುಖ ಸಕಾರಾತ್ಮಕ ಅಂಶವಾಗಿದೆ. ಸಿಗ್ನಲ್‌ಗಳು ಮತ್ತು ಸಂದೇಶಗಳ ಮೂಲಕ ಅಸಮಕಾಲಿಕ ಸಂವಹನಗಳನ್ನು ಬಳಸಿಕೊಂಡು ವಿಭಿನ್ನ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ನಡುವೆ ಸಂಕೀರ್ಣ ಏಕೀಕರಣ ಪ್ರೋಟೋಕಾಲ್‌ಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಪ್ರಕ್ರಿಯೆಯ ವಿಧಾನವನ್ನು ಬಳಸುವ ಸಾಧ್ಯತೆಯನ್ನು ನಾವು ನೋಡಿದ್ದೇವೆ. ನಿರಂತರ ಸ್ಥಿತಿಯ ಉಪಸ್ಥಿತಿಯು ಇದರಲ್ಲಿ ನಿರ್ಣಾಯಕ ಪಾತ್ರವನ್ನು ವಹಿಸುತ್ತದೆ.

ಮೇಲಿನದನ್ನು ಆಧರಿಸಿ, ನಾವು ತೀರ್ಮಾನಿಸಬಹುದು: BPM ಶೈಲಿಯಲ್ಲಿನ ಪ್ರಕ್ರಿಯೆಯ ವಿಧಾನವು ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾದ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತಗೊಳಿಸಲು ವ್ಯಾಪಕ ಶ್ರೇಣಿಯ ಕಾರ್ಯಗಳನ್ನು ಪರಿಹರಿಸಲು ನಮಗೆ ಅನುಮತಿಸುತ್ತದೆ, ಈ ಪ್ರಕ್ರಿಯೆಗಳಲ್ಲಿ ಏಕೀಕರಣ ಚಟುವಟಿಕೆಗಳನ್ನು ಸಾಮರಸ್ಯದಿಂದ ಹೊಂದಿಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು ಸೂಕ್ತವಾದ ಸಂಕೇತದಲ್ಲಿ ಅಳವಡಿಸಲಾದ ಪ್ರಕ್ರಿಯೆಯನ್ನು ದೃಷ್ಟಿಗೋಚರವಾಗಿ ಪ್ರದರ್ಶಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಕಾಪಾಡಿಕೊಳ್ಳುತ್ತದೆ.

ಏಕೀಕರಣ ಮಾದರಿಯಾಗಿ ಸಿಂಕ್ರೊನಸ್ ಕರೆಗಳ ಅನಾನುಕೂಲಗಳು

ಸಿಂಕ್ರೊನಸ್ ಏಕೀಕರಣವು ಸರಳವಾದ ನಿರ್ಬಂಧಿಸುವ ಕರೆಯನ್ನು ಸೂಚಿಸುತ್ತದೆ. ಒಂದು ಉಪವ್ಯವಸ್ಥೆಯು ಸರ್ವರ್ ಸೈಡ್ ಆಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅಗತ್ಯವಿರುವ ವಿಧಾನದೊಂದಿಗೆ API ಅನ್ನು ಬಹಿರಂಗಪಡಿಸುತ್ತದೆ. ಮತ್ತೊಂದು ಉಪವ್ಯವಸ್ಥೆಯು ಕ್ಲೈಂಟ್ ಸೈಡ್ ಆಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಸರಿಯಾದ ಸಮಯದಲ್ಲಿ ಕರೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ಫಲಿತಾಂಶಕ್ಕಾಗಿ ಕಾಯುತ್ತದೆ. ಸಿಸ್ಟಮ್ ಆರ್ಕಿಟೆಕ್ಚರ್ ಅನ್ನು ಅವಲಂಬಿಸಿ, ಕ್ಲೈಂಟ್ ಮತ್ತು ಸರ್ವರ್ ಬದಿಗಳನ್ನು ಒಂದೇ ಅಪ್ಲಿಕೇಶನ್ ಮತ್ತು ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿ ಅಥವಾ ವಿಭಿನ್ನವಾದವುಗಳಲ್ಲಿ ಇರಿಸಬಹುದು. ಎರಡನೆಯ ಸಂದರ್ಭದಲ್ಲಿ, ನೀವು ಕೆಲವು RPC ಅನುಷ್ಠಾನವನ್ನು ಅನ್ವಯಿಸಬೇಕು ಮತ್ತು ನಿಯತಾಂಕಗಳ ಮಾರ್ಶಲಿಂಗ್ ಮತ್ತು ಕರೆಯ ಫಲಿತಾಂಶವನ್ನು ಒದಗಿಸಬೇಕು.

BPM ಶೈಲಿಯ ಏಕೀಕರಣ

ಈ ಏಕೀಕರಣ ಮಾದರಿಯು ಸಾಕಷ್ಟು ದೊಡ್ಡ ಅನಾನುಕೂಲಗಳನ್ನು ಹೊಂದಿದೆ, ಆದರೆ ಅದರ ಸರಳತೆಯಿಂದಾಗಿ ಇದನ್ನು ಆಚರಣೆಯಲ್ಲಿ ವ್ಯಾಪಕವಾಗಿ ಬಳಸಲಾಗುತ್ತದೆ. ಅನುಷ್ಠಾನದ ವೇಗವು ನಿಮ್ಮನ್ನು ಸೆರೆಹಿಡಿಯುತ್ತದೆ ಮತ್ತು ಗಡುವನ್ನು ಒತ್ತುವ ಸಂದರ್ಭದಲ್ಲಿ ಅದನ್ನು ಮತ್ತೆ ಮತ್ತೆ ಬಳಸಲು ನಿಮ್ಮನ್ನು ಒತ್ತಾಯಿಸುತ್ತದೆ, ಪರಿಹಾರವನ್ನು ತಾಂತ್ರಿಕ ಸಾಲವಾಗಿ ದಾಖಲಿಸುತ್ತದೆ. ಆದರೆ ಅನನುಭವಿ ಅಭಿವರ್ಧಕರು ಅದನ್ನು ಅರಿವಿಲ್ಲದೆ ಬಳಸುತ್ತಾರೆ, ಋಣಾತ್ಮಕ ಪರಿಣಾಮಗಳನ್ನು ಅರಿತುಕೊಳ್ಳುವುದಿಲ್ಲ.

ಉಪವ್ಯವಸ್ಥೆಯ ಸಂಪರ್ಕದಲ್ಲಿ ಅತ್ಯಂತ ಸ್ಪಷ್ಟವಾದ ಹೆಚ್ಚಳದ ಜೊತೆಗೆ, "ಬೆಳೆಯುತ್ತಿರುವ" ಮತ್ತು "ವಿಸ್ತರಿಸುವ" ವಹಿವಾಟುಗಳೊಂದಿಗೆ ಕಡಿಮೆ ಸ್ಪಷ್ಟವಾದ ಸಮಸ್ಯೆಗಳಿವೆ. ವಾಸ್ತವವಾಗಿ, ವ್ಯವಹಾರದ ತರ್ಕವು ಕೆಲವು ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಿದರೆ, ವಹಿವಾಟುಗಳನ್ನು ತಪ್ಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ, ಮತ್ತು ವಹಿವಾಟುಗಳು, ಈ ಬದಲಾವಣೆಗಳಿಂದ ಪ್ರಭಾವಿತವಾದ ಕೆಲವು ಅಪ್ಲಿಕೇಶನ್ ಸಂಪನ್ಮೂಲಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತವೆ. ಅಂದರೆ, ಒಂದು ಉಪವ್ಯವಸ್ಥೆಯು ಇನ್ನೊಂದರಿಂದ ಪ್ರತಿಕ್ರಿಯೆಗಾಗಿ ಕಾಯುವವರೆಗೆ, ವ್ಯವಹಾರವನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು ಮತ್ತು ಲಾಕ್‌ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. ಇದು ವಿವಿಧ ಪರಿಣಾಮಗಳ ಅಪಾಯವನ್ನು ಗಮನಾರ್ಹವಾಗಿ ಹೆಚ್ಚಿಸುತ್ತದೆ:

  • ಸಿಸ್ಟಮ್ನ ಸ್ಪಂದಿಸುವಿಕೆಯು ಕಳೆದುಹೋಗಿದೆ, ಬಳಕೆದಾರರು ವಿನಂತಿಗಳಿಗೆ ಉತ್ತರಗಳಿಗಾಗಿ ದೀರ್ಘಕಾಲ ಕಾಯುತ್ತಾರೆ;
  • ಮಿತಿಮೀರಿದ ಥ್ರೆಡ್ ಪೂಲ್‌ನಿಂದಾಗಿ ಸರ್ವರ್ ಸಾಮಾನ್ಯವಾಗಿ ಬಳಕೆದಾರರ ವಿನಂತಿಗಳಿಗೆ ಪ್ರತಿಕ್ರಿಯಿಸುವುದನ್ನು ನಿಲ್ಲಿಸುತ್ತದೆ: ವಹಿವಾಟಿನಿಂದ ಆಕ್ರಮಿಸಿಕೊಂಡಿರುವ ಸಂಪನ್ಮೂಲದಲ್ಲಿ ಹೆಚ್ಚಿನ ಥ್ರೆಡ್‌ಗಳನ್ನು ಲಾಕ್ ಮಾಡಲಾಗಿದೆ;
  • ಡೆಡ್‌ಲಾಕ್‌ಗಳು ಕಾಣಿಸಿಕೊಳ್ಳಲು ಪ್ರಾರಂಭಿಸುತ್ತವೆ: ಅವುಗಳ ಸಂಭವಿಸುವಿಕೆಯ ಸಾಧ್ಯತೆಯು ವಹಿವಾಟಿನ ಅವಧಿ, ವ್ಯವಹಾರದ ತರ್ಕ ಮತ್ತು ವ್ಯವಹಾರದಲ್ಲಿ ಒಳಗೊಂಡಿರುವ ಲಾಕ್‌ಗಳ ಪ್ರಮಾಣವನ್ನು ಬಲವಾಗಿ ಅವಲಂಬಿಸಿರುತ್ತದೆ;
  • ವಹಿವಾಟಿನ ಅವಧಿ ಮೀರುವ ದೋಷಗಳು ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತವೆ;
  • ಕಾರ್ಯಕ್ಕೆ ಹೆಚ್ಚಿನ ಪ್ರಮಾಣದ ಡೇಟಾವನ್ನು ಸಂಸ್ಕರಿಸುವ ಮತ್ತು ಬದಲಾಯಿಸುವ ಅಗತ್ಯವಿದ್ದರೆ ಸರ್ವರ್ OutOfMemory ನೊಂದಿಗೆ "ವಿಫಲಗೊಳ್ಳುತ್ತದೆ" ಮತ್ತು ಸಿಂಕ್ರೊನಸ್ ಏಕೀಕರಣಗಳ ಉಪಸ್ಥಿತಿಯು ಸಂಸ್ಕರಣೆಯನ್ನು "ಹಗುರ" ವಹಿವಾಟುಗಳಾಗಿ ವಿಭಜಿಸಲು ತುಂಬಾ ಕಷ್ಟಕರವಾಗುತ್ತದೆ.

ವಾಸ್ತುಶಿಲ್ಪದ ದೃಷ್ಟಿಕೋನದಿಂದ, ಏಕೀಕರಣದ ಸಮಯದಲ್ಲಿ ಕರೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸುವ ಬಳಕೆಯು ವೈಯಕ್ತಿಕ ಉಪವ್ಯವಸ್ಥೆಗಳ ಗುಣಮಟ್ಟದ ಮೇಲೆ ನಿಯಂತ್ರಣದ ನಷ್ಟಕ್ಕೆ ಕಾರಣವಾಗುತ್ತದೆ: ಒಂದು ಉಪವ್ಯವಸ್ಥೆಯ ಗುರಿ ಗುಣಮಟ್ಟದ ಸೂಚಕಗಳನ್ನು ಮತ್ತೊಂದು ಉಪವ್ಯವಸ್ಥೆಯ ಗುಣಮಟ್ಟದ ಸೂಚಕಗಳಿಂದ ಪ್ರತ್ಯೇಕವಾಗಿ ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವುದು ಅಸಾಧ್ಯ. ಉಪವ್ಯವಸ್ಥೆಗಳನ್ನು ವಿವಿಧ ತಂಡಗಳು ಅಭಿವೃದ್ಧಿಪಡಿಸಿದರೆ, ಇದು ದೊಡ್ಡ ಸಮಸ್ಯೆಯಾಗಿದೆ.

ಸಂಯೋಜಿತವಾಗಿರುವ ಉಪವ್ಯವಸ್ಥೆಗಳು ವಿಭಿನ್ನ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿದ್ದರೆ ಮತ್ತು ನೀವು ಎರಡೂ ಬದಿಗಳಲ್ಲಿ ಸಿಂಕ್ರೊನಸ್ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಬೇಕಾದರೆ ವಿಷಯಗಳು ಇನ್ನಷ್ಟು ಆಸಕ್ತಿದಾಯಕವಾಗುತ್ತವೆ. ಈ ಬದಲಾವಣೆಗಳ ವಹಿವಾಟನ್ನು ಹೇಗೆ ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವುದು?

ಪ್ರತ್ಯೇಕ ವಹಿವಾಟುಗಳಲ್ಲಿ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಿದರೆ, ನೀವು ವಿಶ್ವಾಸಾರ್ಹ ವಿನಾಯಿತಿ ನಿರ್ವಹಣೆ ಮತ್ತು ಪರಿಹಾರವನ್ನು ಒದಗಿಸಬೇಕಾಗುತ್ತದೆ, ಮತ್ತು ಇದು ಸಿಂಕ್ರೊನಸ್ ಏಕೀಕರಣಗಳ ಮುಖ್ಯ ಪ್ರಯೋಜನವನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ನಿವಾರಿಸುತ್ತದೆ - ಸರಳತೆ.

ವಿತರಿಸಿದ ವಹಿವಾಟುಗಳು ಸಹ ಮನಸ್ಸಿಗೆ ಬರುತ್ತವೆ, ಆದರೆ ನಾವು ಅವುಗಳನ್ನು ನಮ್ಮ ಪರಿಹಾರಗಳಲ್ಲಿ ಬಳಸುವುದಿಲ್ಲ: ವಿಶ್ವಾಸಾರ್ಹತೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವುದು ಕಷ್ಟ.

ವಹಿವಾಟಿನ ಸಮಸ್ಯೆಗೆ ಪರಿಹಾರವಾಗಿ "ಸಾಗಾ"

ಮೈಕ್ರೊ ಸರ್ವಿಸ್‌ಗಳ ಜನಪ್ರಿಯತೆ ಹೆಚ್ಚುತ್ತಿದೆ, ಬೇಡಿಕೆ ಸಾಗಾ ಮಾದರಿ.

ಈ ಮಾದರಿಯು ದೀರ್ಘ ವಹಿವಾಟುಗಳ ಮೇಲೆ ತಿಳಿಸಿದ ಸಮಸ್ಯೆಗಳನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಪರಿಹರಿಸುತ್ತದೆ ಮತ್ತು ವ್ಯವಹಾರ ತರ್ಕದ ಬದಿಯಿಂದ ವ್ಯವಸ್ಥೆಯ ಸ್ಥಿತಿಯನ್ನು ನಿರ್ವಹಿಸುವ ಸಾಮರ್ಥ್ಯಗಳನ್ನು ವಿಸ್ತರಿಸುತ್ತದೆ: ವಿಫಲ ವಹಿವಾಟಿನ ನಂತರ ಪರಿಹಾರವು ಸಿಸ್ಟಮ್ ಅನ್ನು ಅದರ ಮೂಲ ಸ್ಥಿತಿಗೆ ಹಿಂತಿರುಗಿಸದೆ ಇರಬಹುದು, ಆದರೆ ಒದಗಿಸುತ್ತದೆ ಪರ್ಯಾಯ ಡೇಟಾ ಸಂಸ್ಕರಣಾ ಮಾರ್ಗ. ಪ್ರಕ್ರಿಯೆಯನ್ನು "ಉತ್ತಮ" ಅಂತ್ಯಕ್ಕೆ ತರಲು ಪ್ರಯತ್ನಿಸುವಾಗ ಯಶಸ್ವಿಯಾಗಿ ಪೂರ್ಣಗೊಂಡ ಡೇಟಾ ಸಂಸ್ಕರಣಾ ಹಂತಗಳನ್ನು ಪುನರಾವರ್ತಿಸುವುದನ್ನು ತಪ್ಪಿಸಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ.

ಕುತೂಹಲಕಾರಿಯಾಗಿ, ಏಕಶಿಲೆಯ ವ್ಯವಸ್ಥೆಗಳಲ್ಲಿ ಈ ಮಾದರಿಯು ಸಡಿಲವಾಗಿ ಜೋಡಿಸಲಾದ ಉಪವ್ಯವಸ್ಥೆಗಳ ಏಕೀಕರಣಕ್ಕೆ ಬಂದಾಗ ಮತ್ತು ದೀರ್ಘಾವಧಿಯ ವಹಿವಾಟುಗಳು ಮತ್ತು ಅನುಗುಣವಾದ ಸಂಪನ್ಮೂಲ ಲಾಕ್‌ಗಳಿಂದ ಉಂಟಾಗುವ ಋಣಾತ್ಮಕ ಪರಿಣಾಮಗಳನ್ನು ಗಮನಿಸಿದಾಗ ಸಹ ಪ್ರಸ್ತುತವಾಗಿದೆ.

BPM ಶೈಲಿಯಲ್ಲಿನ ನಮ್ಮ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳಿಗೆ ಸಂಬಂಧಿಸಿದಂತೆ, "ಸಾಗಾಸ್" ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಇದು ತುಂಬಾ ಸುಲಭವಾಗಿದೆ: "ಸಾಗಾ" ದ ವೈಯಕ್ತಿಕ ಹಂತಗಳನ್ನು ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿನ ಚಟುವಟಿಕೆಗಳಾಗಿ ನಿರ್ದಿಷ್ಟಪಡಿಸಬಹುದು ಮತ್ತು ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಯ ನಿರಂತರ ಸ್ಥಿತಿಯೂ ಸಹ "ಸಾಗಾ" ದ ಆಂತರಿಕ ಸ್ಥಿತಿಯನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ. ಅಂದರೆ, ನಮಗೆ ಯಾವುದೇ ಹೆಚ್ಚುವರಿ ಸಮನ್ವಯ ಕಾರ್ಯವಿಧಾನದ ಅಗತ್ಯವಿಲ್ಲ. ಸಾರಿಗೆಯಾಗಿ "ಕನಿಷ್ಠ ಒಮ್ಮೆ" ಖಾತರಿಗಳನ್ನು ಬೆಂಬಲಿಸುವ ಸಂದೇಶ ಬ್ರೋಕರ್ ನಿಮಗೆ ಬೇಕಾಗಿರುವುದು.

ಆದರೆ ಈ ಪರಿಹಾರವು ತನ್ನದೇ ಆದ "ಬೆಲೆ" ಹೊಂದಿದೆ:

  • ವ್ಯವಹಾರ ತರ್ಕವು ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾಗುತ್ತದೆ: ಪರಿಹಾರವನ್ನು ರೂಪಿಸುವ ಅಗತ್ಯವಿದೆ;
  • ಸಂಪೂರ್ಣ ಸ್ಥಿರತೆಯನ್ನು ತ್ಯಜಿಸುವುದು ಅಗತ್ಯವಾಗಿರುತ್ತದೆ, ಇದು ಏಕಶಿಲೆಯ ವ್ಯವಸ್ಥೆಗಳಿಗೆ ವಿಶೇಷವಾಗಿ ಸೂಕ್ಷ್ಮವಾಗಿರುತ್ತದೆ;
  • ವಾಸ್ತುಶಿಲ್ಪವು ಸ್ವಲ್ಪ ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾಗುತ್ತದೆ ಮತ್ತು ಸಂದೇಶ ಬ್ರೋಕರ್‌ನ ಹೆಚ್ಚುವರಿ ಅಗತ್ಯವು ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ;
  • ಹೆಚ್ಚುವರಿ ಮೇಲ್ವಿಚಾರಣೆ ಮತ್ತು ಆಡಳಿತ ಪರಿಕರಗಳ ಅಗತ್ಯವಿರುತ್ತದೆ (ಸಾಮಾನ್ಯವಾಗಿ ಇದು ಒಳ್ಳೆಯದು: ಸಿಸ್ಟಮ್ ಸೇವೆಯ ಗುಣಮಟ್ಟ ಹೆಚ್ಚಾಗುತ್ತದೆ).

ಏಕಶಿಲೆಯ ವ್ಯವಸ್ಥೆಗಳಿಗೆ, "ಸಾಗ್" ಅನ್ನು ಬಳಸುವ ಸಮರ್ಥನೆಯು ಅಷ್ಟು ಸ್ಪಷ್ಟವಾಗಿಲ್ಲ. ಮೈಕ್ರೋಸರ್ವಿಸ್ ಮತ್ತು ಇತರ SOA ಗಾಗಿ, ಈಗಾಗಲೇ ಬ್ರೋಕರ್ ಇರುವ ಸಾಧ್ಯತೆಯಿದೆ ಮತ್ತು ಯೋಜನೆಯ ಪ್ರಾರಂಭದಲ್ಲಿ ಪೂರ್ಣ ಸ್ಥಿರತೆಯನ್ನು ತ್ಯಾಗ ಮಾಡಲಾಗುತ್ತದೆ, ಈ ಮಾದರಿಯನ್ನು ಬಳಸುವ ಪ್ರಯೋಜನಗಳು ಅನಾನುಕೂಲಗಳನ್ನು ಗಮನಾರ್ಹವಾಗಿ ಮೀರಿಸುತ್ತದೆ, ವಿಶೇಷವಾಗಿ ವ್ಯಾಪಾರ ತರ್ಕದಲ್ಲಿ ಅನುಕೂಲಕರ API ಇದ್ದರೆ. ಮಟ್ಟದ.

ಮೈಕ್ರೋ ಸರ್ವೀಸ್‌ನಲ್ಲಿ ವ್ಯಾಪಾರ ತರ್ಕವನ್ನು ಎನ್‌ಕ್ಯಾಪ್ಸುಲೇಟಿಂಗ್ ಮಾಡುವುದು

ನಾವು ಮೈಕ್ರೋಸರ್ವಿಸ್‌ಗಳೊಂದಿಗೆ ಪ್ರಯೋಗವನ್ನು ಪ್ರಾರಂಭಿಸಿದಾಗ, ಒಂದು ಸಮಂಜಸವಾದ ಪ್ರಶ್ನೆಯು ಉದ್ಭವಿಸಿತು: ಡೊಮೇನ್ ಡೇಟಾದ ನಿರಂತರತೆಯನ್ನು ಖಾತ್ರಿಪಡಿಸುವ ಸೇವೆಗೆ ಸಂಬಂಧಿಸಿದಂತೆ ಡೊಮೇನ್ ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಎಲ್ಲಿ ಇರಿಸಬೇಕು?

ವಿವಿಧ BPMS ಗಳ ಆರ್ಕಿಟೆಕ್ಚರ್ ಅನ್ನು ನೋಡುವಾಗ, ವ್ಯಾಪಾರ ತರ್ಕವನ್ನು ನಿರಂತರತೆಯಿಂದ ಪ್ರತ್ಯೇಕಿಸುವುದು ಸಮಂಜಸವಾಗಿ ಕಾಣಿಸಬಹುದು: ಡೊಮೇನ್ ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಪರಿಸರ ಮತ್ತು ಧಾರಕವನ್ನು ರೂಪಿಸುವ ವೇದಿಕೆ ಮತ್ತು ಡೊಮೇನ್-ಸ್ವತಂತ್ರ ಮೈಕ್ರೋ ಸರ್ವೀಸ್‌ಗಳ ಪದರವನ್ನು ರಚಿಸಿ ಮತ್ತು ಡೊಮೇನ್ ಡೇಟಾದ ನಿರಂತರತೆಯನ್ನು ವಿನ್ಯಾಸಗೊಳಿಸಿ ಅತ್ಯಂತ ಸರಳ ಮತ್ತು ಹಗುರವಾದ ಸೂಕ್ಷ್ಮ ಸೇವೆಗಳ ಪ್ರತ್ಯೇಕ ಪದರ. ಈ ಸಂದರ್ಭದಲ್ಲಿ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳು ನಿರಂತರ ಪದರದ ಸೇವೆಗಳ ಆರ್ಕೆಸ್ಟ್ರೇಶನ್ ಅನ್ನು ನಿರ್ವಹಿಸುತ್ತವೆ.

BPM ಶೈಲಿಯ ಏಕೀಕರಣ

ಈ ವಿಧಾನವು ಬಹಳ ದೊಡ್ಡ ಪ್ರಯೋಜನವನ್ನು ಹೊಂದಿದೆ: ನೀವು ಇಷ್ಟಪಡುವಷ್ಟು ಪ್ಲಾಟ್‌ಫಾರ್ಮ್‌ನ ಕಾರ್ಯವನ್ನು ನೀವು ಹೆಚ್ಚಿಸಬಹುದು ಮತ್ತು ಪ್ಲಾಟ್‌ಫಾರ್ಮ್ ಮೈಕ್ರೋಸರ್ವೀಸ್‌ಗಳ ಅನುಗುಣವಾದ ಪದರ ಮಾತ್ರ ಇದರಿಂದ “ಕೊಬ್ಬು” ಆಗುತ್ತದೆ. ಯಾವುದೇ ಡೊಮೇನ್‌ನಿಂದ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳು ಪ್ಲಾಟ್‌ಫಾರ್ಮ್‌ನ ಹೊಸ ಕಾರ್ಯವನ್ನು ನವೀಕರಿಸಿದ ತಕ್ಷಣ ಅದನ್ನು ಬಳಸಲು ತಕ್ಷಣವೇ ಸಾಧ್ಯವಾಗುತ್ತದೆ.

ಹೆಚ್ಚು ವಿವರವಾದ ಅಧ್ಯಯನವು ಈ ವಿಧಾನದ ಗಮನಾರ್ಹ ಅನಾನುಕೂಲಗಳನ್ನು ಬಹಿರಂಗಪಡಿಸಿದೆ:

  • ಅನೇಕ ಡೊಮೇನ್‌ಗಳ ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಏಕಕಾಲದಲ್ಲಿ ಕಾರ್ಯಗತಗೊಳಿಸುವ ಪ್ಲಾಟ್‌ಫಾರ್ಮ್ ಸೇವೆಯು ವೈಫಲ್ಯದ ಒಂದು ಬಿಂದುವಾಗಿ ದೊಡ್ಡ ಅಪಾಯಗಳನ್ನು ಹೊಂದಿರುತ್ತದೆ. ವ್ಯಾಪಾರ ತರ್ಕಕ್ಕೆ ಆಗಾಗ್ಗೆ ಬದಲಾವಣೆಗಳು ಸಿಸ್ಟಮ್-ವೈಡ್ ವೈಫಲ್ಯಗಳಿಗೆ ಕಾರಣವಾಗುವ ದೋಷಗಳ ಅಪಾಯವನ್ನು ಹೆಚ್ಚಿಸುತ್ತವೆ;
  • ಕಾರ್ಯಕ್ಷಮತೆಯ ಸಮಸ್ಯೆಗಳು: ವ್ಯಾಪಾರ ತರ್ಕವು ಅದರ ಡೇಟಾದೊಂದಿಗೆ ಕಿರಿದಾದ ಮತ್ತು ನಿಧಾನವಾದ ಇಂಟರ್ಫೇಸ್ ಮೂಲಕ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ:
    • ಡೇಟಾವನ್ನು ಮತ್ತೊಮ್ಮೆ ಮಾರ್ಷಲ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ನೆಟ್ವರ್ಕ್ ಸ್ಟಾಕ್ ಮೂಲಕ ಪಂಪ್ ಮಾಡಲಾಗುತ್ತದೆ;
    • ಸೇವೆಯ ಬಾಹ್ಯ API ಯ ಮಟ್ಟದಲ್ಲಿ ವಿನಂತಿಗಳನ್ನು ಪ್ಯಾರಾಮೀಟರ್ ಮಾಡಲು ಸಾಕಷ್ಟು ಸಾಮರ್ಥ್ಯಗಳ ಕೊರತೆಯಿಂದಾಗಿ ಡೊಮೇನ್ ಸೇವೆಯು ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಅಗತ್ಯಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಡೇಟಾವನ್ನು ಒದಗಿಸುತ್ತದೆ;
    • ವ್ಯವಹಾರ ತರ್ಕದ ಹಲವಾರು ಸ್ವತಂತ್ರ ತುಣುಕುಗಳು ಪ್ರಕ್ರಿಯೆಗಾಗಿ ಅದೇ ಡೇಟಾವನ್ನು ಪುನರಾವರ್ತಿತವಾಗಿ ಮರು ವಿನಂತಿಸಬಹುದು (ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸುವ ಸೆಷನ್ ಘಟಕಗಳನ್ನು ಸೇರಿಸುವ ಮೂಲಕ ಈ ಸಮಸ್ಯೆಯನ್ನು ತಗ್ಗಿಸಬಹುದು, ಆದರೆ ಇದು ವಾಸ್ತುಶಿಲ್ಪವನ್ನು ಇನ್ನಷ್ಟು ಸಂಕೀರ್ಣಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ಡೇಟಾ ಪ್ರಸ್ತುತತೆ ಮತ್ತು ಕ್ಯಾಶ್ ಅಮಾನ್ಯತೆಯ ಸಮಸ್ಯೆಗಳನ್ನು ಸೃಷ್ಟಿಸುತ್ತದೆ);
  • ವಹಿವಾಟಿನ ಸಮಸ್ಯೆಗಳು:
    • ಪ್ಲಾಟ್‌ಫಾರ್ಮ್ ಸೇವೆಯಿಂದ ಸಂಗ್ರಹಿಸಲಾದ ನಿರಂತರ ಸ್ಥಿತಿಯೊಂದಿಗೆ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳು ಡೊಮೇನ್ ಡೇಟಾದೊಂದಿಗೆ ಅಸಮಂಜಸವಾಗಿದೆ ಮತ್ತು ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು ಯಾವುದೇ ಸುಲಭ ಮಾರ್ಗಗಳಿಲ್ಲ;
    • ವಹಿವಾಟಿನ ಹೊರಗೆ ಡೊಮೇನ್ ಡೇಟಾವನ್ನು ನಿರ್ಬಂಧಿಸುವುದು: ಪ್ರಸ್ತುತ ಡೇಟಾದ ಸರಿಯಾದತೆಯನ್ನು ಮೊದಲು ಪರಿಶೀಲಿಸಿದ ನಂತರ ಡೊಮೇನ್ ವ್ಯವಹಾರ ತರ್ಕವು ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಬೇಕಾದರೆ, ಸಂಸ್ಕರಿಸಿದ ಡೇಟಾದಲ್ಲಿ ಸ್ಪರ್ಧಾತ್ಮಕ ಬದಲಾವಣೆಯ ಸಾಧ್ಯತೆಯನ್ನು ಹೊರತುಪಡಿಸುವುದು ಅವಶ್ಯಕ. ಬಾಹ್ಯ ಡೇಟಾ ನಿರ್ಬಂಧಿಸುವಿಕೆಯು ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ, ಆದರೆ ಅಂತಹ ಪರಿಹಾರವು ಹೆಚ್ಚುವರಿ ಅಪಾಯಗಳನ್ನು ಹೊಂದಿರುತ್ತದೆ ಮತ್ತು ಸಿಸ್ಟಮ್ನ ಒಟ್ಟಾರೆ ವಿಶ್ವಾಸಾರ್ಹತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ;
  • ನವೀಕರಿಸುವಾಗ ಹೆಚ್ಚುವರಿ ತೊಂದರೆಗಳು: ಕೆಲವು ಸಂದರ್ಭಗಳಲ್ಲಿ, ನಿರಂತರ ಸೇವೆ ಮತ್ತು ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಸಿಂಕ್ರೊನಸ್ ಆಗಿ ಅಥವಾ ಕಟ್ಟುನಿಟ್ಟಾದ ಅನುಕ್ರಮದಲ್ಲಿ ನವೀಕರಿಸಬೇಕಾಗುತ್ತದೆ.

ಅಂತಿಮವಾಗಿ, ನಾವು ಬೇಸಿಕ್ಸ್‌ಗೆ ಹಿಂತಿರುಗಬೇಕಾಗಿತ್ತು: ಡೊಮೇನ್ ಡೇಟಾ ಮತ್ತು ಡೊಮೇನ್ ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಒಂದು ಮೈಕ್ರೋ ಸರ್ವಿಸ್ ಆಗಿ ಎನ್‌ಕ್ಯಾಪ್ಸುಲೇಟ್ ಮಾಡಿ. ಈ ವಿಧಾನವು ಮೈಕ್ರೋಸರ್ವಿಸ್ ಅನ್ನು ಸಿಸ್ಟಮ್ನ ಅವಿಭಾಜ್ಯ ಅಂಗವಾಗಿ ಗ್ರಹಿಕೆಯನ್ನು ಸರಳಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ಮೇಲಿನ ಸಮಸ್ಯೆಗಳಿಗೆ ಕಾರಣವಾಗುವುದಿಲ್ಲ. ಇದನ್ನು ಉಚಿತವಾಗಿ ನೀಡಲಾಗುವುದಿಲ್ಲ:

  • ವ್ಯಾಪಾರ ತರ್ಕ (ನಿರ್ದಿಷ್ಟವಾಗಿ, ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳ ಭಾಗವಾಗಿ ಬಳಕೆದಾರರ ಚಟುವಟಿಕೆಗಳನ್ನು ಒದಗಿಸಲು) ಮತ್ತು API ಪ್ಲಾಟ್‌ಫಾರ್ಮ್ ಸೇವೆಗಳೊಂದಿಗೆ ಸಂವಹನಕ್ಕಾಗಿ API ಪ್ರಮಾಣೀಕರಣದ ಅಗತ್ಯವಿದೆ; API ಬದಲಾವಣೆಗಳು, ಫಾರ್ವರ್ಡ್ ಮತ್ತು ಬ್ಯಾಕ್‌ವರ್ಡ್ ಹೊಂದಾಣಿಕೆಗೆ ಹೆಚ್ಚು ಎಚ್ಚರಿಕೆಯ ಗಮನದ ಅಗತ್ಯವಿದೆ;
  • ಅಂತಹ ಪ್ರತಿಯೊಂದು ಮೈಕ್ರೊ ಸರ್ವಿಸ್‌ನ ಭಾಗವಾಗಿ ವ್ಯವಹಾರ ತರ್ಕದ ಕಾರ್ಯನಿರ್ವಹಣೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಹೆಚ್ಚುವರಿ ರನ್‌ಟೈಮ್ ಲೈಬ್ರರಿಗಳನ್ನು ಸೇರಿಸುವುದು ಅವಶ್ಯಕ, ಮತ್ತು ಇದು ಅಂತಹ ಗ್ರಂಥಾಲಯಗಳಿಗೆ ಹೊಸ ಅವಶ್ಯಕತೆಗಳಿಗೆ ಕಾರಣವಾಗುತ್ತದೆ: ಲಘುತೆ ಮತ್ತು ಕನಿಷ್ಠ ಟ್ರಾನ್ಸಿಟಿವ್ ಅವಲಂಬನೆಗಳು;
  • ಬಿಸಿನೆಸ್ ಲಾಜಿಕ್ ಡೆವಲಪರ್‌ಗಳು ಲೈಬ್ರರಿ ಆವೃತ್ತಿಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬೇಕಾಗುತ್ತದೆ: ಮೈಕ್ರೋ ಸರ್ವಿಸ್ ಅನ್ನು ದೀರ್ಘಕಾಲದವರೆಗೆ ಅಂತಿಮಗೊಳಿಸದಿದ್ದರೆ, ಅದು ಹೆಚ್ಚಾಗಿ ಗ್ರಂಥಾಲಯಗಳ ಹಳೆಯ ಆವೃತ್ತಿಯನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಹೊಸ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಸೇರಿಸಲು ಇದು ಅನಿರೀಕ್ಷಿತ ಅಡಚಣೆಯಾಗಿರಬಹುದು ಮತ್ತು ಆವೃತ್ತಿಗಳ ನಡುವೆ ಹೊಂದಾಣಿಕೆಯಾಗದ ಬದಲಾವಣೆಗಳಿದ್ದರೆ ಅಂತಹ ಸೇವೆಯ ಹಳೆಯ ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಹೊಸ ಆವೃತ್ತಿಯ ಲೈಬ್ರರಿಗಳಿಗೆ ಸ್ಥಳಾಂತರಿಸುವ ಅಗತ್ಯವಿರಬಹುದು.

BPM ಶೈಲಿಯ ಏಕೀಕರಣ

ಅಂತಹ ಆರ್ಕಿಟೆಕ್ಚರ್‌ನಲ್ಲಿ ಪ್ಲಾಟ್‌ಫಾರ್ಮ್ ಸೇವೆಗಳ ಪದರವು ಸಹ ಇರುತ್ತದೆ, ಆದರೆ ಈ ಪದರವು ಇನ್ನು ಮುಂದೆ ಡೊಮೇನ್ ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಧಾರಕವನ್ನು ರೂಪಿಸುವುದಿಲ್ಲ, ಆದರೆ ಅದರ ಪರಿಸರ ಮಾತ್ರ, ಸಹಾಯಕ "ಪ್ಲಾಟ್‌ಫಾರ್ಮ್" ಕಾರ್ಯಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ. ಅಂತಹ ಪದರವು ಡೊಮೇನ್ ಮೈಕ್ರೊ ಸರ್ವಿಸ್‌ಗಳ ಹಗುರವಾದ ಸ್ವಭಾವವನ್ನು ಕಾಪಾಡಿಕೊಳ್ಳಲು ಮಾತ್ರವಲ್ಲದೆ ನಿರ್ವಹಣೆಯನ್ನು ಕೇಂದ್ರೀಕರಿಸಲು ಸಹ ಅಗತ್ಯವಿದೆ.

ಉದಾಹರಣೆಗೆ, ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳಲ್ಲಿ ಬಳಕೆದಾರರ ಚಟುವಟಿಕೆಗಳು ಕಾರ್ಯಗಳನ್ನು ಸೃಷ್ಟಿಸುತ್ತವೆ. ಆದಾಗ್ಯೂ, ಕಾರ್ಯಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ, ಬಳಕೆದಾರರು ಸಾಮಾನ್ಯ ಪಟ್ಟಿಯಲ್ಲಿರುವ ಎಲ್ಲಾ ಡೊಮೇನ್‌ಗಳಿಂದ ಕಾರ್ಯಗಳನ್ನು ನೋಡಬೇಕು, ಅಂದರೆ ಡೊಮೇನ್ ವ್ಯವಹಾರ ತರ್ಕದಿಂದ ತೆರವುಗೊಳಿಸಲಾದ ಅನುಗುಣವಾದ ವೇದಿಕೆ ಕಾರ್ಯ ನೋಂದಣಿ ಸೇವೆ ಇರಬೇಕು. ಅಂತಹ ಸಂದರ್ಭದಲ್ಲಿ ವ್ಯವಹಾರ ತರ್ಕದ ಎನ್ಕ್ಯಾಪ್ಸುಲೇಶನ್ ಅನ್ನು ನಿರ್ವಹಿಸುವುದು ಸಾಕಷ್ಟು ಸಮಸ್ಯಾತ್ಮಕವಾಗಿದೆ ಮತ್ತು ಇದು ಈ ವಾಸ್ತುಶಿಲ್ಪದ ಮತ್ತೊಂದು ರಾಜಿಯಾಗಿದೆ.

ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್ ಕಣ್ಣುಗಳ ಮೂಲಕ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳ ಏಕೀಕರಣ

ಮೇಲೆ ಹೇಳಿದಂತೆ, ಹಲವಾರು ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಪರಸ್ಪರ ಕ್ರಿಯೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ತಾಂತ್ರಿಕ ಮತ್ತು ಎಂಜಿನಿಯರಿಂಗ್ ವೈಶಿಷ್ಟ್ಯಗಳಿಂದ ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್ ಅನ್ನು ಅಮೂರ್ತಗೊಳಿಸಬೇಕು ಇದರಿಂದ ಒಬ್ಬರು ಉತ್ತಮ ಅಭಿವೃದ್ಧಿ ಉತ್ಪಾದಕತೆಯನ್ನು ನಂಬಬಹುದು.

ಲೇಖನಕ್ಕಾಗಿ ವಿಶೇಷವಾಗಿ ಕಂಡುಹಿಡಿದ ಕಷ್ಟಕರವಾದ ಏಕೀಕರಣ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು ಪ್ರಯತ್ನಿಸೋಣ. ಇದು ಮೂರು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಒಳಗೊಂಡ "ಆಟ" ಕಾರ್ಯವಾಗಿದೆ, ಅಲ್ಲಿ ಪ್ರತಿಯೊಂದೂ ಡೊಮೇನ್ ಹೆಸರನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ: "app1", "app2", "app3".

ಪ್ರತಿ ಅಪ್ಲಿಕೇಶನ್ ಒಳಗೆ, ಏಕೀಕರಣ ಬಸ್ ಮೂಲಕ "ಚೆಂಡನ್ನು ಆಡಲು" ಪ್ರಾರಂಭಿಸುವ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತದೆ. "ಬಾಲ್" ಹೆಸರಿನ ಸಂದೇಶಗಳು ಚೆಂಡಿನಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ.

ಆಟದ ನಿಯಮಗಳು:

  • ಮೊದಲ ಆಟಗಾರನು ಇನಿಶಿಯೇಟರ್. ಅವನು ಇತರ ಆಟಗಾರರನ್ನು ಆಟಕ್ಕೆ ಆಹ್ವಾನಿಸುತ್ತಾನೆ, ಆಟವನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತಾನೆ ಮತ್ತು ಅದನ್ನು ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಕೊನೆಗೊಳಿಸಬಹುದು;
  • ಇತರ ಆಟಗಾರರು ಆಟದಲ್ಲಿ ತಮ್ಮ ಭಾಗವಹಿಸುವಿಕೆಯನ್ನು ಘೋಷಿಸುತ್ತಾರೆ, ಪರಸ್ಪರ ಮತ್ತು ಮೊದಲ ಆಟಗಾರನನ್ನು "ತಿಳಿದುಕೊಳ್ಳಿ";
  • ಚೆಂಡನ್ನು ಸ್ವೀಕರಿಸಿದ ನಂತರ, ಆಟಗಾರನು ಭಾಗವಹಿಸುವ ಇನ್ನೊಬ್ಬ ಆಟಗಾರನನ್ನು ಆಯ್ಕೆಮಾಡುತ್ತಾನೆ ಮತ್ತು ಚೆಂಡನ್ನು ಅವನಿಗೆ ರವಾನಿಸುತ್ತಾನೆ. ಪ್ರಸರಣಗಳ ಒಟ್ಟು ಸಂಖ್ಯೆಯನ್ನು ಎಣಿಸಲಾಗಿದೆ;
  • ಪ್ರತಿಯೊಬ್ಬ ಆಟಗಾರನು "ಶಕ್ತಿ" ಯನ್ನು ಹೊಂದಿದ್ದು ಆ ಆಟಗಾರನು ಚೆಂಡಿನ ಪ್ರತಿ ಪಾಸ್‌ನೊಂದಿಗೆ ಕಡಿಮೆಯಾಗುತ್ತದೆ. ಶಕ್ತಿಯು ಖಾಲಿಯಾದಾಗ, ಆಟಗಾರನು ಆಟವನ್ನು ಬಿಡುತ್ತಾನೆ, ತನ್ನ ರಾಜೀನಾಮೆಯನ್ನು ಘೋಷಿಸುತ್ತಾನೆ;
  • ಆಟಗಾರನು ಒಬ್ಬಂಟಿಯಾಗಿದ್ದರೆ, ಅವನು ತಕ್ಷಣವೇ ತನ್ನ ನಿರ್ಗಮನವನ್ನು ಘೋಷಿಸುತ್ತಾನೆ;
  • ಎಲ್ಲಾ ಆಟಗಾರರು ಹೊರಹಾಕಲ್ಪಟ್ಟಾಗ, ಮೊದಲ ಆಟಗಾರನು ಆಟ ಮುಗಿದಿದೆ ಎಂದು ಘೋಷಿಸುತ್ತಾನೆ. ಅವನು ಬೇಗನೆ ಆಟವನ್ನು ತೊರೆದರೆ, ಅವನು ಅದನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು ಆಟವನ್ನು ಅನುಸರಿಸುತ್ತಾನೆ.

ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು, ನಾನು ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳಿಗಾಗಿ ನಮ್ಮ DSL ಅನ್ನು ಬಳಸುತ್ತೇನೆ, ಇದು ಕನಿಷ್ಠ ಬಾಯ್ಲರ್‌ಪ್ಲೇಟ್‌ನೊಂದಿಗೆ ಕೋಟ್ಲಿನ್‌ನಲ್ಲಿನ ತರ್ಕವನ್ನು ಸಂಕ್ಷಿಪ್ತವಾಗಿ ವಿವರಿಸಲು ನಮಗೆ ಅನುಮತಿಸುತ್ತದೆ.

ಮೊದಲ ಆಟಗಾರನ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯು (ಆಟದ ಪ್ರಾರಂಭಿಕ) app1 ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ:

ವರ್ಗ ಆರಂಭಿಕ ಆಟಗಾರ

import ru.krista.bpm.ProcessInstance
import ru.krista.bpm.runtime.ProcessImpl
import ru.krista.bpm.runtime.constraint.UniqueConstraints
import ru.krista.bpm.runtime.dsl.processModel
import ru.krista.bpm.runtime.dsl.taskOperation
import ru.krista.bpm.runtime.instance.MessageSendInstance

data class PlayerInfo(val name: String, val domain: String, val id: String)

class PlayersList : ArrayList<PlayerInfo>()

// Это класс экземпляра процесса: инкапсулирует его внутреннее состояние
class InitialPlayer : ProcessImpl<InitialPlayer>(initialPlayerModel) {
    var playerName: String by persistent("Player1")
    var energy: Int by persistent(30)
    var players: PlayersList by persistent(PlayersList())
    var shotCounter: Int = 0
}

// Это декларация модели процесса: создается один раз, используется всеми
// экземплярами процесса соответствующего класса
val initialPlayerModel = processModel<InitialPlayer>(name = "InitialPlayer",
                                                     version = 1) {

    // По правилам, первый игрок является инициатором игры и должен быть единственным
    uniqueConstraint = UniqueConstraints.singleton

    // Объявляем активности, из которых состоит бизнес-процесс
    val sendNewGameSignal = signal<String>("NewGame")
    val sendStopGameSignal = signal<String>("StopGame")
    val startTask = humanTask("Start") {
        taskOperation {
            processCondition { players.size > 0 }
            confirmation { "Подключилось ${players.size} игроков. Начинаем?" }
        }
    }
    val stopTask = humanTask("Stop") {
        taskOperation {}
    }
    val waitPlayerJoin = signalWait<String>("PlayerJoin") { signal ->
        players.add(PlayerInfo(
                signal.data!!,
                signal.sender.domain,
                signal.sender.processInstanceId))
        println("... join player ${signal.data} ...")
    }
    val waitPlayerOut = signalWait<String>("PlayerOut") { signal ->
        players.remove(PlayerInfo(
                signal.data!!,
                signal.sender.domain,
                signal.sender.processInstanceId))
        println("... player ${signal.data} is out ...")
    }
    val sendPlayerOut = signal<String>("PlayerOut") {
        signalData = { playerName }
    }
    val sendHandshake = messageSend<String>("Handshake") {
        messageData = { playerName }
        activation = {
            receiverDomain = process.players.last().domain
            receiverProcessInstanceId = process.players.last().id
        }
    }
    val throwStartBall = messageSend<Int>("Ball") {
        messageData = { 1 }
        activation = { selectNextPlayer() }
    }
    val throwBall = messageSend<Int>("Ball") {
        messageData = { shotCounter + 1 }
        activation = { selectNextPlayer() }
        onEntry { energy -= 1 }
    }
    val waitBall = messageWaitData<Int>("Ball") {
        shotCounter = it
    }

    // Теперь конструируем граф процесса из объявленных активностей
    startFrom(sendNewGameSignal)
            .fork("mainFork") {
                next(startTask)
                next(waitPlayerJoin).next(sendHandshake).next(waitPlayerJoin)
                next(waitPlayerOut)
                        .branch("checkPlayers") {
                            ifTrue { players.isEmpty() }
                                    .next(sendStopGameSignal)
                                    .terminate()
                            ifElse().next(waitPlayerOut)
                        }
            }
    startTask.fork("afterStart") {
        next(throwStartBall)
                .branch("mainLoop") {
                    ifTrue { energy < 5 }.next(sendPlayerOut).next(waitBall)
                    ifElse().next(waitBall).next(throwBall).loop()
                }
        next(stopTask).next(sendStopGameSignal)
    }

    // Навешаем на активности дополнительные обработчики для логирования
    sendNewGameSignal.onExit { println("Let's play!") }
    sendStopGameSignal.onExit { println("Stop!") }
    sendPlayerOut.onExit { println("$playerName: I'm out!") }
}

private fun MessageSendInstance<InitialPlayer, Int>.selectNextPlayer() {
    val player = process.players.random()
    receiverDomain = player.domain
    receiverProcessInstanceId = player.id
    println("Step ${process.shotCounter + 1}: " +
            "${process.playerName} >>> ${player.name}")
}

ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದರ ಜೊತೆಗೆ, ಮೇಲಿನ ಕೋಡ್ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ವಸ್ತು ಮಾದರಿಯನ್ನು ಉತ್ಪಾದಿಸಬಹುದು, ಅದನ್ನು ರೇಖಾಚಿತ್ರದ ರೂಪದಲ್ಲಿ ದೃಶ್ಯೀಕರಿಸಬಹುದು. ನಾವು ಇನ್ನೂ ದೃಶ್ಯೀಕರಣವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿಲ್ಲ, ಆದ್ದರಿಂದ ನಾವು ಸ್ವಲ್ಪ ಸಮಯವನ್ನು ಡ್ರಾಯಿಂಗ್ ಮಾಡಬೇಕಾಗಿತ್ತು (ಕೆಳಗಿನ ಕೋಡ್‌ನೊಂದಿಗೆ ರೇಖಾಚಿತ್ರದ ಸ್ಥಿರತೆಯನ್ನು ಸುಧಾರಿಸಲು ಗೇಟ್‌ಗಳ ಬಳಕೆಗೆ ಸಂಬಂಧಿಸಿದಂತೆ ನಾನು BPMN ಸಂಕೇತವನ್ನು ಸ್ವಲ್ಪ ಸರಳಗೊಳಿಸಿದ್ದೇನೆ):

BPM ಶೈಲಿಯ ಏಕೀಕರಣ

app2 ಇತರ ಆಟಗಾರರ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ:

ವರ್ಗ ರಾಂಡಮ್ ಪ್ಲೇಯರ್

import ru.krista.bpm.ProcessInstance
import ru.krista.bpm.runtime.ProcessImpl
import ru.krista.bpm.runtime.dsl.processModel
import ru.krista.bpm.runtime.instance.MessageSendInstance

data class PlayerInfo(val name: String, val domain: String, val id: String)

class PlayersList: ArrayList<PlayerInfo>()

class RandomPlayer : ProcessImpl<RandomPlayer>(randomPlayerModel) {

    var playerName: String by input(persistent = true, 
                                    defaultValue = "RandomPlayer")
    var energy: Int by input(persistent = true, defaultValue = 30)
    var players: PlayersList by persistent(PlayersList())
    var allPlayersOut: Boolean by persistent(false)
    var shotCounter: Int = 0

    val selfPlayer: PlayerInfo
        get() = PlayerInfo(playerName, env.eventDispatcher.domainName, id)
}

val randomPlayerModel = processModel<RandomPlayer>(name = "RandomPlayer", 
                                                   version = 1) {

    val waitNewGameSignal = signalWait<String>("NewGame")
    val waitStopGameSignal = signalWait<String>("StopGame")
    val sendPlayerJoin = signal<String>("PlayerJoin") {
        signalData = { playerName }
    }
    val sendPlayerOut = signal<String>("PlayerOut") {
        signalData = { playerName }
    }
    val waitPlayerJoin = signalWaitCustom<String>("PlayerJoin") {
        eventCondition = { signal ->
            signal.sender.processInstanceId != process.id 
                && !process.players.any { signal.sender.processInstanceId == it.id}
        }
        handler = { signal ->
            players.add(PlayerInfo(
                    signal.data!!,
                    signal.sender.domain,
                    signal.sender.processInstanceId))
        }
    }
    val waitPlayerOut = signalWait<String>("PlayerOut") { signal ->
        players.remove(PlayerInfo(
                signal.data!!,
                signal.sender.domain,
                signal.sender.processInstanceId))
        allPlayersOut = players.isEmpty()
    }
    val sendHandshake = messageSend<String>("Handshake") {
        messageData = { playerName }
        activation = {
            receiverDomain = process.players.last().domain
            receiverProcessInstanceId = process.players.last().id
        }
    }
    val receiveHandshake = messageWait<String>("Handshake") { message ->
        if (!players.any { message.sender.processInstanceId == it.id}) {
            players.add(PlayerInfo(
                    message.data!!, 
                    message.sender.domain, 
                    message.sender.processInstanceId))
        }
    }
    val throwBall = messageSend<Int>("Ball") {
        messageData = { shotCounter + 1 }
        activation = { selectNextPlayer() }
        onEntry { energy -= 1 }
    }
    val waitBall = messageWaitData<Int>("Ball") {
        shotCounter = it
    }

    startFrom(waitNewGameSignal)
            .fork("mainFork") {
                next(sendPlayerJoin)
                        .branch("mainLoop") {
                            ifTrue { energy < 5 || allPlayersOut }
                                    .next(sendPlayerOut)
                                    .next(waitBall)
                            ifElse()
                                    .next(waitBall)
                                    .next(throwBall)
                                    .loop()
                        }
                next(waitPlayerJoin).next(sendHandshake).next(waitPlayerJoin)
                next(waitPlayerOut).next(waitPlayerOut)
                next(receiveHandshake).next(receiveHandshake)
                next(waitStopGameSignal).terminate()
            }

    sendPlayerJoin.onExit { println("$playerName: I'm here!") }
    sendPlayerOut.onExit { println("$playerName: I'm out!") }
}

private fun MessageSendInstance<RandomPlayer, Int>.selectNextPlayer() {
    val player = if (process.players.isNotEmpty()) 
        process.players.random() 
    else 
        process.selfPlayer
    receiverDomain = player.domain
    receiverProcessInstanceId = player.id
    println("Step ${process.shotCounter + 1}: " +
            "${process.playerName} >>> ${player.name}")
}

ರೇಖಾಚಿತ್ರ:

BPM ಶೈಲಿಯ ಏಕೀಕರಣ

app3 ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ನಾವು ಸ್ವಲ್ಪ ವಿಭಿನ್ನ ನಡವಳಿಕೆಯನ್ನು ಹೊಂದಿರುವ ಆಟಗಾರನನ್ನು ಮಾಡುತ್ತೇವೆ: ಮುಂದಿನ ಆಟಗಾರನನ್ನು ಯಾದೃಚ್ಛಿಕವಾಗಿ ಆಯ್ಕೆ ಮಾಡುವ ಬದಲು, ಅವರು ರೌಂಡ್-ರಾಬಿನ್ ಅಲ್ಗಾರಿದಮ್ ಪ್ರಕಾರ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಾರೆ:

ವರ್ಗ ರೌಂಡ್‌ರಾಬಿನ್ ಪ್ಲೇಯರ್

import ru.krista.bpm.ProcessInstance
import ru.krista.bpm.runtime.ProcessImpl
import ru.krista.bpm.runtime.dsl.processModel
import ru.krista.bpm.runtime.instance.MessageSendInstance

data class PlayerInfo(val name: String, val domain: String, val id: String)

class PlayersList: ArrayList<PlayerInfo>()

class RoundRobinPlayer : ProcessImpl<RoundRobinPlayer>(roundRobinPlayerModel) {

    var playerName: String by input(persistent = true, 
                                    defaultValue = "RoundRobinPlayer")
    var energy: Int by input(persistent = true, defaultValue = 30)
    var players: PlayersList by persistent(PlayersList())
    var nextPlayerIndex: Int by persistent(-1)
    var allPlayersOut: Boolean by persistent(false)
    var shotCounter: Int = 0

    val selfPlayer: PlayerInfo
        get() = PlayerInfo(playerName, env.eventDispatcher.domainName, id)
}

val roundRobinPlayerModel = processModel<RoundRobinPlayer>(
        name = "RoundRobinPlayer", 
        version = 1) {

    val waitNewGameSignal = signalWait<String>("NewGame")
    val waitStopGameSignal = signalWait<String>("StopGame")
    val sendPlayerJoin = signal<String>("PlayerJoin") {
        signalData = { playerName }
    }
    val sendPlayerOut = signal<String>("PlayerOut") {
        signalData = { playerName }
    }
    val waitPlayerJoin = signalWaitCustom<String>("PlayerJoin") {
        eventCondition = { signal ->
            signal.sender.processInstanceId != process.id 
                && !process.players.any { signal.sender.processInstanceId == it.id}
        }
        handler = { signal ->
            players.add(PlayerInfo(
                    signal.data!!, 
                    signal.sender.domain, 
                    signal.sender.processInstanceId))
        }
    }
    val waitPlayerOut = signalWait<String>("PlayerOut") { signal ->
        players.remove(PlayerInfo(
                signal.data!!, 
                signal.sender.domain, 
                signal.sender.processInstanceId))
        allPlayersOut = players.isEmpty()
    }
    val sendHandshake = messageSend<String>("Handshake") {
        messageData = { playerName }
        activation = {
            receiverDomain = process.players.last().domain
            receiverProcessInstanceId = process.players.last().id
        }
    }
    val receiveHandshake = messageWait<String>("Handshake") { message ->
        if (!players.any { message.sender.processInstanceId == it.id}) {
            players.add(PlayerInfo(
                    message.data!!, 
                    message.sender.domain, 
                    message.sender.processInstanceId))
        }
    }
    val throwBall = messageSend<Int>("Ball") {
        messageData = { shotCounter + 1 }
        activation = { selectNextPlayer() }
        onEntry { energy -= 1 }
    }
    val waitBall = messageWaitData<Int>("Ball") {
        shotCounter = it
    }

    startFrom(waitNewGameSignal)
            .fork("mainFork") {
                next(sendPlayerJoin)
                        .branch("mainLoop") {
                            ifTrue { energy < 5 || allPlayersOut }
                                    .next(sendPlayerOut)
                                    .next(waitBall)
                            ifElse()
                                    .next(waitBall)
                                    .next(throwBall)
                                    .loop()
                        }
                next(waitPlayerJoin).next(sendHandshake).next(waitPlayerJoin)
                next(waitPlayerOut).next(waitPlayerOut)
                next(receiveHandshake).next(receiveHandshake)
                next(waitStopGameSignal).terminate()
            }

    sendPlayerJoin.onExit { println("$playerName: I'm here!") }
    sendPlayerOut.onExit { println("$playerName: I'm out!") }
}

private fun MessageSendInstance<RoundRobinPlayer, Int>.selectNextPlayer() {
    var idx = process.nextPlayerIndex + 1
    if (idx >= process.players.size) {
        idx = 0
    }
    process.nextPlayerIndex = idx
    val player = if (process.players.isNotEmpty()) 
        process.players[idx] 
    else 
        process.selfPlayer
    receiverDomain = player.domain
    receiverProcessInstanceId = player.id
    println("Step ${process.shotCounter + 1}: " +
            "${process.playerName} >>> ${player.name}")
}

ಇಲ್ಲದಿದ್ದರೆ, ಆಟಗಾರನ ನಡವಳಿಕೆಯು ಹಿಂದಿನದಕ್ಕಿಂತ ಭಿನ್ನವಾಗಿರುವುದಿಲ್ಲ, ಆದ್ದರಿಂದ ರೇಖಾಚಿತ್ರವು ಬದಲಾಗುವುದಿಲ್ಲ.

ಈಗ ಇದೆಲ್ಲವನ್ನೂ ನಡೆಸಲು ನಮಗೆ ಪರೀಕ್ಷೆಯ ಅಗತ್ಯವಿದೆ. ಬಾಯ್ಲರ್‌ಪ್ಲೇಟ್‌ನೊಂದಿಗೆ ಲೇಖನವನ್ನು ಅಸ್ತವ್ಯಸ್ತಗೊಳಿಸದಂತೆ ನಾನು ಪರೀಕ್ಷೆಯ ಕೋಡ್ ಅನ್ನು ಮಾತ್ರ ನೀಡುತ್ತೇನೆ (ವಾಸ್ತವವಾಗಿ, ಇತರ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳ ಏಕೀಕರಣವನ್ನು ಪರೀಕ್ಷಿಸಲು ನಾನು ಮೊದಲು ರಚಿಸಲಾದ ಪರೀಕ್ಷಾ ವಾತಾವರಣವನ್ನು ಬಳಸಿದ್ದೇನೆ):

ಟೆಸ್ಟ್‌ಗೇಮ್()

@Test
public void testGame() throws InterruptedException {
    String pl2 = startProcess(app2, "RandomPlayer", playerParams("Player2", 20));
    String pl3 = startProcess(app2, "RandomPlayer", playerParams("Player3", 40));
    String pl4 = startProcess(app3, "RoundRobinPlayer", playerParams("Player4", 25));
    String pl5 = startProcess(app3, "RoundRobinPlayer", playerParams("Player5", 35));
    String pl1 = startProcess(app1, "InitialPlayer");
    // Теперь нужно немного подождать, пока игроки "познакомятся" друг с другом.
    // Ждать через sleep - плохое решение, зато самое простое. 
    // Не делайте так в серьезных тестах!
    Thread.sleep(1000);
    // Запускаем игру, закрывая пользовательскую активность
    assertTrue(closeTask(app1, pl1, "Start"));
    app1.getWaiting().waitProcessFinished(pl1);
    app2.getWaiting().waitProcessFinished(pl2);
    app2.getWaiting().waitProcessFinished(pl3);
    app3.getWaiting().waitProcessFinished(pl4);
    app3.getWaiting().waitProcessFinished(pl5);
}

private Map<String, Object> playerParams(String name, int energy) {
    Map<String, Object> params = new HashMap<>();
    params.put("playerName", name);
    params.put("energy", energy);
    return params;
}

ಪರೀಕ್ಷೆಯನ್ನು ನಡೆಸೋಣ ಮತ್ತು ಲಾಗ್ ಅನ್ನು ನೋಡೋಣ:

ಕನ್ಸೋಲ್ ಔಟ್ಪುಟ್

Взята блокировка ключа lock://app1/process/InitialPlayer
Let's play!
Снята блокировка ключа lock://app1/process/InitialPlayer
Player2: I'm here!
Player3: I'm here!
Player4: I'm here!
Player5: I'm here!
... join player Player2 ...
... join player Player4 ...
... join player Player3 ...
... join player Player5 ...
Step 1: Player1 >>> Player3
Step 2: Player3 >>> Player5
Step 3: Player5 >>> Player3
Step 4: Player3 >>> Player4
Step 5: Player4 >>> Player3
Step 6: Player3 >>> Player4
Step 7: Player4 >>> Player5
Step 8: Player5 >>> Player2
Step 9: Player2 >>> Player5
Step 10: Player5 >>> Player4
Step 11: Player4 >>> Player2
Step 12: Player2 >>> Player4
Step 13: Player4 >>> Player1
Step 14: Player1 >>> Player4
Step 15: Player4 >>> Player3
Step 16: Player3 >>> Player1
Step 17: Player1 >>> Player2
Step 18: Player2 >>> Player3
Step 19: Player3 >>> Player1
Step 20: Player1 >>> Player5
Step 21: Player5 >>> Player1
Step 22: Player1 >>> Player2
Step 23: Player2 >>> Player4
Step 24: Player4 >>> Player5
Step 25: Player5 >>> Player3
Step 26: Player3 >>> Player4
Step 27: Player4 >>> Player2
Step 28: Player2 >>> Player5
Step 29: Player5 >>> Player2
Step 30: Player2 >>> Player1
Step 31: Player1 >>> Player3
Step 32: Player3 >>> Player4
Step 33: Player4 >>> Player1
Step 34: Player1 >>> Player3
Step 35: Player3 >>> Player4
Step 36: Player4 >>> Player3
Step 37: Player3 >>> Player2
Step 38: Player2 >>> Player5
Step 39: Player5 >>> Player4
Step 40: Player4 >>> Player5
Step 41: Player5 >>> Player1
Step 42: Player1 >>> Player5
Step 43: Player5 >>> Player3
Step 44: Player3 >>> Player5
Step 45: Player5 >>> Player2
Step 46: Player2 >>> Player3
Step 47: Player3 >>> Player2
Step 48: Player2 >>> Player5
Step 49: Player5 >>> Player4
Step 50: Player4 >>> Player2
Step 51: Player2 >>> Player5
Step 52: Player5 >>> Player1
Step 53: Player1 >>> Player5
Step 54: Player5 >>> Player3
Step 55: Player3 >>> Player5
Step 56: Player5 >>> Player2
Step 57: Player2 >>> Player1
Step 58: Player1 >>> Player4
Step 59: Player4 >>> Player1
Step 60: Player1 >>> Player4
Step 61: Player4 >>> Player3
Step 62: Player3 >>> Player2
Step 63: Player2 >>> Player5
Step 64: Player5 >>> Player4
Step 65: Player4 >>> Player5
Step 66: Player5 >>> Player1
Step 67: Player1 >>> Player5
Step 68: Player5 >>> Player3
Step 69: Player3 >>> Player4
Step 70: Player4 >>> Player2
Step 71: Player2 >>> Player5
Step 72: Player5 >>> Player2
Step 73: Player2 >>> Player1
Step 74: Player1 >>> Player4
Step 75: Player4 >>> Player1
Step 76: Player1 >>> Player2
Step 77: Player2 >>> Player5
Step 78: Player5 >>> Player4
Step 79: Player4 >>> Player3
Step 80: Player3 >>> Player1
Step 81: Player1 >>> Player5
Step 82: Player5 >>> Player1
Step 83: Player1 >>> Player4
Step 84: Player4 >>> Player5
Step 85: Player5 >>> Player3
Step 86: Player3 >>> Player5
Step 87: Player5 >>> Player2
Step 88: Player2 >>> Player3
Player2: I'm out!
Step 89: Player3 >>> Player4
... player Player2 is out ...
Step 90: Player4 >>> Player1
Step 91: Player1 >>> Player3
Step 92: Player3 >>> Player1
Step 93: Player1 >>> Player4
Step 94: Player4 >>> Player3
Step 95: Player3 >>> Player5
Step 96: Player5 >>> Player1
Step 97: Player1 >>> Player5
Step 98: Player5 >>> Player3
Step 99: Player3 >>> Player5
Step 100: Player5 >>> Player4
Step 101: Player4 >>> Player5
Player4: I'm out!
... player Player4 is out ...
Step 102: Player5 >>> Player1
Step 103: Player1 >>> Player3
Step 104: Player3 >>> Player1
Step 105: Player1 >>> Player3
Step 106: Player3 >>> Player5
Step 107: Player5 >>> Player3
Step 108: Player3 >>> Player1
Step 109: Player1 >>> Player3
Step 110: Player3 >>> Player5
Step 111: Player5 >>> Player1
Step 112: Player1 >>> Player3
Step 113: Player3 >>> Player5
Step 114: Player5 >>> Player3
Step 115: Player3 >>> Player1
Step 116: Player1 >>> Player3
Step 117: Player3 >>> Player5
Step 118: Player5 >>> Player1
Step 119: Player1 >>> Player3
Step 120: Player3 >>> Player5
Step 121: Player5 >>> Player3
Player5: I'm out!
... player Player5 is out ...
Step 122: Player3 >>> Player5
Step 123: Player5 >>> Player1
Player5: I'm out!
Step 124: Player1 >>> Player3
... player Player5 is out ...
Step 125: Player3 >>> Player1
Step 126: Player1 >>> Player3
Player1: I'm out!
... player Player1 is out ...
Step 127: Player3 >>> Player3
Player3: I'm out!
Step 128: Player3 >>> Player3
... player Player3 is out ...
Player3: I'm out!
Stop!
Step 129: Player3 >>> Player3
Player3: I'm out!

ಈ ಎಲ್ಲದರಿಂದ ನಾವು ಹಲವಾರು ಪ್ರಮುಖ ತೀರ್ಮಾನಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಬಹುದು:

  • ಅಗತ್ಯ ಪರಿಕರಗಳೊಂದಿಗೆ, ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್‌ಗಳು ವ್ಯವಹಾರ ತರ್ಕಕ್ಕೆ ಅಡ್ಡಿಯಾಗದಂತೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ನಡುವೆ ಏಕೀಕರಣ ಸಂವಹನಗಳನ್ನು ರಚಿಸಬಹುದು;
  • ಎಂಜಿನಿಯರಿಂಗ್ ಸಾಮರ್ಥ್ಯಗಳ ಅಗತ್ಯವಿರುವ ಏಕೀಕರಣ ಕಾರ್ಯದ ಸಂಕೀರ್ಣತೆಯನ್ನು ಚೌಕಟ್ಟಿನೊಳಗೆ ಮರೆಮಾಡಬಹುದು, ಇದನ್ನು ಆರಂಭದಲ್ಲಿ ಚೌಕಟ್ಟಿನ ವಾಸ್ತುಶಿಲ್ಪದಲ್ಲಿ ಸೇರಿಸಲಾಗುತ್ತದೆ. ಸಮಸ್ಯೆಯ ಕಷ್ಟವನ್ನು ಮರೆಮಾಡಲಾಗುವುದಿಲ್ಲ, ಆದ್ದರಿಂದ ಕೋಡ್‌ನಲ್ಲಿ ಕಠಿಣ ಸಮಸ್ಯೆಯ ಪರಿಹಾರವು ಹಾಗೆ ಕಾಣುತ್ತದೆ;
  • ಏಕೀಕರಣ ತರ್ಕವನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸುವಾಗ, ಎಲ್ಲಾ ಏಕೀಕರಣ ಭಾಗವಹಿಸುವವರ ಸ್ಥಿತಿಯಲ್ಲಿನ ಬದಲಾವಣೆಗಳ ಅಂತಿಮ ಸ್ಥಿರತೆ ಮತ್ತು ರೇಖಾತ್ಮಕತೆಯ ಕೊರತೆಯನ್ನು ಗಣನೆಗೆ ತೆಗೆದುಕೊಳ್ಳುವುದು ಕಡ್ಡಾಯವಾಗಿದೆ. ಬಾಹ್ಯ ಘಟನೆಗಳು ಸಂಭವಿಸುವ ಕ್ರಮಕ್ಕೆ ಸಂವೇದನಾಶೀಲವಾಗದಂತೆ ಮಾಡಲು ಇದು ತರ್ಕವನ್ನು ಸಂಕೀರ್ಣಗೊಳಿಸಲು ನಮ್ಮನ್ನು ಒತ್ತಾಯಿಸುತ್ತದೆ. ನಮ್ಮ ಉದಾಹರಣೆಯಲ್ಲಿ, ಆಟಗಾರನು ಆಟದಿಂದ ತನ್ನ ನಿರ್ಗಮನವನ್ನು ಘೋಷಿಸಿದ ನಂತರ ಆಟದಲ್ಲಿ ಪಾಲ್ಗೊಳ್ಳಲು ಒತ್ತಾಯಿಸಲಾಗುತ್ತದೆ: ಇತರ ಆಟಗಾರರು ಅವನ ನಿರ್ಗಮನದ ಬಗ್ಗೆ ಮಾಹಿತಿಯು ತಲುಪುವವರೆಗೆ ಮತ್ತು ಎಲ್ಲಾ ಭಾಗವಹಿಸುವವರಿಂದ ಪ್ರಕ್ರಿಯೆಗೊಳ್ಳುವವರೆಗೆ ಅವನಿಗೆ ಚೆಂಡನ್ನು ರವಾನಿಸುವುದನ್ನು ಮುಂದುವರಿಸುತ್ತಾರೆ. ಈ ತರ್ಕವು ಆಟದ ನಿಯಮಗಳಿಂದ ಅನುಸರಿಸುವುದಿಲ್ಲ ಮತ್ತು ಆಯ್ಕೆಮಾಡಿದ ವಾಸ್ತುಶಿಲ್ಪದ ಚೌಕಟ್ಟಿನೊಳಗೆ ರಾಜಿ ಪರಿಹಾರವಾಗಿದೆ.

ಮುಂದೆ, ನಮ್ಮ ಪರಿಹಾರ, ಹೊಂದಾಣಿಕೆಗಳು ಮತ್ತು ಇತರ ಅಂಶಗಳ ವಿವಿಧ ಜಟಿಲತೆಗಳ ಬಗ್ಗೆ ನಾವು ಮಾತನಾಡುತ್ತೇವೆ.

ಎಲ್ಲಾ ಸಂದೇಶಗಳು ಒಂದೇ ಸಾಲಿನಲ್ಲಿವೆ

ಎಲ್ಲಾ ಸಂಯೋಜಿತ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಒಂದು ಏಕೀಕರಣ ಬಸ್‌ನೊಂದಿಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ, ಇದನ್ನು ಬಾಹ್ಯ ಬ್ರೋಕರ್ ರೂಪದಲ್ಲಿ ಪ್ರಸ್ತುತಪಡಿಸಲಾಗುತ್ತದೆ, ಸಂದೇಶಗಳಿಗಾಗಿ ಒಂದು BPMQueue ಮತ್ತು ಸಂಕೇತಗಳಿಗಾಗಿ ಒಂದು BPMTopic ವಿಷಯ (ಈವೆಂಟ್‌ಗಳು). ಎಲ್ಲಾ ಸಂದೇಶಗಳನ್ನು ಒಂದೇ ಸರದಿಯಲ್ಲಿ ಹಾಕುವುದು ಸ್ವತಃ ರಾಜಿಯಾಗಿದೆ. ವ್ಯವಹಾರ ತರ್ಕ ಮಟ್ಟದಲ್ಲಿ, ಸಿಸ್ಟಮ್ ರಚನೆಯಲ್ಲಿ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡದೆಯೇ ನೀವು ಈಗ ನೀವು ಇಷ್ಟಪಡುವಷ್ಟು ಹೊಸ ಸಂದೇಶ ಪ್ರಕಾರಗಳನ್ನು ಪರಿಚಯಿಸಬಹುದು. ಇದು ಗಮನಾರ್ಹವಾದ ಸರಳೀಕರಣವಾಗಿದೆ, ಆದರೆ ಇದು ಕೆಲವು ಅಪಾಯಗಳನ್ನು ಹೊಂದಿದೆ, ಇದು ನಮ್ಮ ವಿಶಿಷ್ಟ ಕಾರ್ಯಗಳ ಸಂದರ್ಭದಲ್ಲಿ ನಮಗೆ ಅಷ್ಟು ಮಹತ್ವದ್ದಾಗಿಲ್ಲ.

BPM ಶೈಲಿಯ ಏಕೀಕರಣ

ಆದಾಗ್ಯೂ, ಇಲ್ಲಿ ಒಂದು ಸೂಕ್ಷ್ಮತೆ ಇದೆ: ಪ್ರತಿ ಅಪ್ಲಿಕೇಶನ್ ಅದರ ಡೊಮೇನ್ ಹೆಸರಿನ ಮೂಲಕ ಪ್ರವೇಶದ್ವಾರದಲ್ಲಿರುವ ಸರದಿಯಿಂದ "ಅದರ" ಸಂದೇಶಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡುತ್ತದೆ. ನೀವು ಸಿಗ್ನಲ್‌ನ "ಗೋಚರತೆಯ ವ್ಯಾಪ್ತಿ" ಅನ್ನು ಒಂದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಸೀಮಿತಗೊಳಿಸಬೇಕಾದರೆ ಡೊಮೇನ್ ಅನ್ನು ಸಂಕೇತಗಳಲ್ಲಿ ಸಹ ನಿರ್ದಿಷ್ಟಪಡಿಸಬಹುದು. ಇದು ಬಸ್ ಥ್ರೋಪುಟ್ ಅನ್ನು ಹೆಚ್ಚಿಸಬೇಕು, ಆದರೆ ವ್ಯವಹಾರ ತರ್ಕವು ಈಗ ಡೊಮೇನ್ ಹೆಸರುಗಳೊಂದಿಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸಬೇಕು: ಸಂದೇಶಗಳನ್ನು ಸಂಬೋಧಿಸಲು - ಕಡ್ಡಾಯ, ಸಂಕೇತಗಳಿಗೆ - ಅಪೇಕ್ಷಣೀಯವಾಗಿದೆ.

ಏಕೀಕರಣ ಬಸ್ ವಿಶ್ವಾಸಾರ್ಹತೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವುದು

ವಿಶ್ವಾಸಾರ್ಹತೆಯು ಹಲವಾರು ಅಂಶಗಳನ್ನು ಒಳಗೊಂಡಿದೆ:

  • ಆಯ್ದ ಸಂದೇಶ ಬ್ರೋಕರ್ ವಾಸ್ತುಶಿಲ್ಪದ ಒಂದು ನಿರ್ಣಾಯಕ ಅಂಶವಾಗಿದೆ ಮತ್ತು ವೈಫಲ್ಯದ ಏಕೈಕ ಅಂಶವಾಗಿದೆ: ಇದು ಸಾಕಷ್ಟು ದೋಷ-ಸಹಿಷ್ಣುವಾಗಿರಬೇಕು. ಉತ್ತಮ ಬೆಂಬಲ ಮತ್ತು ದೊಡ್ಡ ಸಮುದಾಯದೊಂದಿಗೆ ನೀವು ಸಮಯ-ಪರೀಕ್ಷಿತ ಅನುಷ್ಠಾನಗಳನ್ನು ಮಾತ್ರ ಬಳಸಬೇಕು;
  • ಸಂದೇಶ ಬ್ರೋಕರ್‌ನ ಹೆಚ್ಚಿನ ಲಭ್ಯತೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವುದು ಅಗತ್ಯವಾಗಿದೆ, ಇದಕ್ಕಾಗಿ ಅದನ್ನು ಸಮಗ್ರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಂದ ಭೌತಿಕವಾಗಿ ಬೇರ್ಪಡಿಸಬೇಕು (ಅನ್ವಯಿಕ ವ್ಯವಹಾರ ತರ್ಕದೊಂದಿಗೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಹೆಚ್ಚಿನ ಲಭ್ಯತೆ ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಹೆಚ್ಚು ಕಷ್ಟ ಮತ್ತು ದುಬಾರಿಯಾಗಿದೆ);
  • "ಕನಿಷ್ಠ ಒಮ್ಮೆ" ವಿತರಣಾ ಖಾತರಿಗಳನ್ನು ಒದಗಿಸಲು ಬ್ರೋಕರ್ ನಿರ್ಬಂಧಿತನಾಗಿರುತ್ತಾನೆ. ಏಕೀಕರಣ ಬಸ್ನ ವಿಶ್ವಾಸಾರ್ಹ ಕಾರ್ಯಾಚರಣೆಗೆ ಇದು ಕಡ್ಡಾಯ ಅವಶ್ಯಕತೆಯಾಗಿದೆ. "ನಿಖರವಾಗಿ ಒಮ್ಮೆ" ಮಟ್ಟದ ಖಾತರಿಗಳ ಅಗತ್ಯವಿಲ್ಲ: ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳು, ನಿಯಮದಂತೆ, ಸಂದೇಶಗಳು ಅಥವಾ ಈವೆಂಟ್‌ಗಳ ಪುನರಾವರ್ತಿತ ಆಗಮನಕ್ಕೆ ಸೂಕ್ಷ್ಮವಾಗಿರುವುದಿಲ್ಲ ಮತ್ತು ಇದು ಮುಖ್ಯವಾದ ವಿಶೇಷ ಕಾರ್ಯಗಳಲ್ಲಿ, ವ್ಯವಹಾರಕ್ಕೆ ಹೆಚ್ಚುವರಿ ಚೆಕ್‌ಗಳನ್ನು ಸೇರಿಸುವುದು ಸುಲಭ. ಸಾಕಷ್ಟು "ದುಬಾರಿ" "ಗ್ಯಾರಂಟಿಗಳನ್ನು ನಿರಂತರವಾಗಿ ಬಳಸುವುದಕ್ಕಿಂತ ತರ್ಕ;
  • ಸಂದೇಶಗಳು ಮತ್ತು ಸಂಕೇತಗಳನ್ನು ಕಳುಹಿಸುವುದು ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳು ಮತ್ತು ಡೊಮೇನ್ ಡೇಟಾದ ಸ್ಥಿತಿಯ ಬದಲಾವಣೆಗಳೊಂದಿಗೆ ಒಟ್ಟಾರೆ ವಹಿವಾಟಿನಲ್ಲಿ ತೊಡಗಿಸಿಕೊಂಡಿರಬೇಕು. ಮಾದರಿಯನ್ನು ಬಳಸುವುದು ಆದ್ಯತೆಯ ಆಯ್ಕೆಯಾಗಿದೆ ವಹಿವಾಟಿನ ಔಟ್‌ಬಾಕ್ಸ್, ಆದರೆ ಇದಕ್ಕೆ ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಹೆಚ್ಚುವರಿ ಟೇಬಲ್ ಮತ್ತು ರಿಪೀಟರ್ ಅಗತ್ಯವಿರುತ್ತದೆ. JEE ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿ, ಸ್ಥಳೀಯ JTA ಮ್ಯಾನೇಜರ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಇದನ್ನು ಸರಳಗೊಳಿಸಬಹುದು, ಆದರೆ ಆಯ್ಕೆಮಾಡಿದ ಬ್ರೋಕರ್‌ಗೆ ಸಂಪರ್ಕವು ಕೆಲಸ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ XA;
  • ಒಳಬರುವ ಸಂದೇಶಗಳು ಮತ್ತು ಈವೆಂಟ್‌ಗಳ ನಿರ್ವಾಹಕರು ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಸ್ಥಿತಿಯನ್ನು ಬದಲಾಯಿಸುವ ವ್ಯವಹಾರದೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಬೇಕು: ಅಂತಹ ವಹಿವಾಟನ್ನು ಹಿಂದಕ್ಕೆ ತೆಗೆದುಕೊಂಡರೆ, ಸಂದೇಶದ ರಶೀದಿಯನ್ನು ರದ್ದುಗೊಳಿಸಬೇಕು;
  • ದೋಷಗಳಿಂದಾಗಿ ತಲುಪಿಸಲು ಸಾಧ್ಯವಾಗದ ಸಂದೇಶಗಳನ್ನು ಪ್ರತ್ಯೇಕ ಸಂಗ್ರಹಣೆಯಲ್ಲಿ ಸಂಗ್ರಹಿಸಬೇಕು ಡಿ.ಎಲ್.ಕ್ಯೂ. (ಡೆಡ್ ಲೆಟರ್ ಕ್ಯೂ). ಈ ಉದ್ದೇಶಕ್ಕಾಗಿ, ನಾವು ಅಂತಹ ಸಂದೇಶಗಳನ್ನು ಅದರ ಸಂಗ್ರಹಣೆಯಲ್ಲಿ ಸಂಗ್ರಹಿಸುವ ಪ್ರತ್ಯೇಕ ಪ್ಲಾಟ್‌ಫಾರ್ಮ್ ಮೈಕ್ರೋಸರ್ವಿಸ್ ಅನ್ನು ರಚಿಸಿದ್ದೇವೆ, ಅವುಗಳನ್ನು ಗುಣಲಕ್ಷಣಗಳ ಮೂಲಕ ಸೂಚ್ಯಂಕಗೊಳಿಸುತ್ತೇವೆ (ತ್ವರಿತ ಗುಂಪು ಮಾಡುವಿಕೆ ಮತ್ತು ಹುಡುಕಾಟಕ್ಕಾಗಿ), ಮತ್ತು ವೀಕ್ಷಿಸಲು, ಗಮ್ಯಸ್ಥಾನದ ವಿಳಾಸಕ್ಕೆ ಮರುಕಳಿಸಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಅಳಿಸಲು API ಅನ್ನು ಬಹಿರಂಗಪಡಿಸುತ್ತೇವೆ. ಸಿಸ್ಟಮ್ ನಿರ್ವಾಹಕರು ತಮ್ಮ ವೆಬ್ ಇಂಟರ್ಫೇಸ್ ಮೂಲಕ ಈ ಸೇವೆಯೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಬಹುದು;
  • ಬ್ರೋಕರ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ, DLQ ಗೆ ಸಂದೇಶಗಳು ಬರುವ ಸಾಧ್ಯತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಲು ನೀವು ವಿತರಣಾ ಮರುಪ್ರಯತ್ನಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮತ್ತು ವಿತರಣೆಗಳ ನಡುವಿನ ವಿಳಂಬವನ್ನು ಸರಿಹೊಂದಿಸಬೇಕಾಗಿದೆ (ಸೂಕ್ತ ನಿಯತಾಂಕಗಳನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡುವುದು ಬಹುತೇಕ ಅಸಾಧ್ಯ, ಆದರೆ ನೀವು ಪ್ರಾಯೋಗಿಕವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸಬಹುದು ಮತ್ತು ಕಾರ್ಯಾಚರಣೆಯ ಸಮಯದಲ್ಲಿ ಅವುಗಳನ್ನು ಸರಿಹೊಂದಿಸಬಹುದು. );
  • DLQ ಅಂಗಡಿಯನ್ನು ನಿರಂತರವಾಗಿ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬೇಕು, ಮತ್ತು ಮೇಲ್ವಿಚಾರಣಾ ವ್ಯವಸ್ಥೆಯು ಸಿಸ್ಟಮ್ ನಿರ್ವಾಹಕರನ್ನು ಎಚ್ಚರಿಸಬೇಕು, ಇದರಿಂದಾಗಿ ತಲುಪಿಸದ ಸಂದೇಶಗಳು ಸಂಭವಿಸಿದಾಗ, ಅವರು ಸಾಧ್ಯವಾದಷ್ಟು ಬೇಗ ಪ್ರತಿಕ್ರಿಯಿಸಬಹುದು. ಇದು ವೈಫಲ್ಯ ಅಥವಾ ವ್ಯವಹಾರ ತರ್ಕ ದೋಷದ "ಬಾಧಿತ ಪ್ರದೇಶ" ವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ;
  • ಇಂಟಿಗ್ರೇಷನ್ ಬಸ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ತಾತ್ಕಾಲಿಕ ಅನುಪಸ್ಥಿತಿಗೆ ಸೂಕ್ಷ್ಮವಲ್ಲದದ್ದಾಗಿರಬೇಕು: ವಿಷಯದ ಚಂದಾದಾರಿಕೆಗಳು ಬಾಳಿಕೆ ಬರುವಂತಿರಬೇಕು ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್‌ನ ಡೊಮೇನ್ ಹೆಸರು ಅನನ್ಯವಾಗಿರಬೇಕು ಆದ್ದರಿಂದ ಅಪ್ಲಿಕೇಶನ್ ಇಲ್ಲದಿರುವಾಗ, ಬೇರೆಯವರು ಅದರ ಸಂದೇಶಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಪ್ರಯತ್ನಿಸುವುದಿಲ್ಲ ಕ್ಯೂ.

ವ್ಯಾಪಾರ ತರ್ಕದ ಥ್ರೆಡ್ ಸುರಕ್ಷತೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವುದು

ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಅದೇ ನಿದರ್ಶನವು ಹಲವಾರು ಸಂದೇಶಗಳು ಮತ್ತು ಈವೆಂಟ್‌ಗಳನ್ನು ಏಕಕಾಲದಲ್ಲಿ ಸ್ವೀಕರಿಸಬಹುದು, ಅದರ ಪ್ರಕ್ರಿಯೆಯು ಸಮಾನಾಂತರವಾಗಿ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ. ಅದೇ ಸಮಯದಲ್ಲಿ, ಅಪ್ಲಿಕೇಶನ್ ಡೆವಲಪರ್ಗಾಗಿ, ಎಲ್ಲವೂ ಸರಳ ಮತ್ತು ಥ್ರೆಡ್-ಸುರಕ್ಷಿತವಾಗಿರಬೇಕು.

ಪ್ರಕ್ರಿಯೆಯ ವ್ಯವಹಾರ ತರ್ಕವು ಪ್ರತಿ ಬಾಹ್ಯ ಘಟನೆಯನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುತ್ತದೆ, ಅದು ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಮೇಲೆ ಪ್ರತ್ಯೇಕವಾಗಿ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ. ಅಂತಹ ಘಟನೆಗಳು ಹೀಗಿರಬಹುದು:

  • ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಉದಾಹರಣೆಯನ್ನು ಪ್ರಾರಂಭಿಸುವುದು;
  • ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಯೊಳಗಿನ ಚಟುವಟಿಕೆಗೆ ಸಂಬಂಧಿಸಿದ ಬಳಕೆದಾರರ ಕ್ರಿಯೆ;
  • ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ನಿದರ್ಶನವನ್ನು ಚಂದಾದಾರರಾಗಿರುವ ಸಂದೇಶ ಅಥವಾ ಸಂಕೇತದ ಸ್ವೀಕೃತಿ;
  • ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಯ ನಿದರ್ಶನದಿಂದ ಹೊಂದಿಸಲಾದ ಟೈಮರ್ ಅನ್ನು ಪ್ರಚೋದಿಸುವುದು;
  • API ಮೂಲಕ ನಿಯಂತ್ರಣ ಕ್ರಿಯೆ (ಉದಾಹರಣೆಗೆ, ಪ್ರಕ್ರಿಯೆ ಅಡಚಣೆ).

ಅಂತಹ ಪ್ರತಿಯೊಂದು ಘಟನೆಯು ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ನಿದರ್ಶನದ ಸ್ಥಿತಿಯನ್ನು ಬದಲಾಯಿಸಬಹುದು: ಕೆಲವು ಚಟುವಟಿಕೆಗಳು ಕೊನೆಗೊಳ್ಳಬಹುದು ಮತ್ತು ಇತರರು ಪ್ರಾರಂಭವಾಗಬಹುದು ಮತ್ತು ನಿರಂತರ ಗುಣಲಕ್ಷಣಗಳ ಮೌಲ್ಯಗಳು ಬದಲಾಗಬಹುದು. ಯಾವುದೇ ಚಟುವಟಿಕೆಯನ್ನು ಮುಚ್ಚುವುದರಿಂದ ಈ ಕೆಳಗಿನ ಒಂದು ಅಥವಾ ಹೆಚ್ಚಿನ ಚಟುವಟಿಕೆಗಳ ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆಗೆ ಕಾರಣವಾಗಬಹುದು. ಅವರು ಪ್ರತಿಯಾಗಿ, ಇತರ ಈವೆಂಟ್‌ಗಳಿಗಾಗಿ ಕಾಯುವುದನ್ನು ನಿಲ್ಲಿಸಬಹುದು ಅಥವಾ ಅವರಿಗೆ ಯಾವುದೇ ಹೆಚ್ಚುವರಿ ಡೇಟಾ ಅಗತ್ಯವಿಲ್ಲದಿದ್ದರೆ, ಅದೇ ವಹಿವಾಟಿನಲ್ಲಿ ಪೂರ್ಣಗೊಳಿಸಬಹುದು. ವಹಿವಾಟನ್ನು ಮುಚ್ಚುವ ಮೊದಲು, ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಹೊಸ ಸ್ಥಿತಿಯನ್ನು ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಉಳಿಸಲಾಗುತ್ತದೆ, ಅಲ್ಲಿ ಅದು ಮುಂದಿನ ಬಾಹ್ಯ ಈವೆಂಟ್ ಸಂಭವಿಸುವವರೆಗೆ ಕಾಯುತ್ತದೆ.

ರಿಲೇಶನಲ್ ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ನಿರಂತರ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆ ಡೇಟಾವು ನೀವು ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿದರೆ ಸಂಸ್ಕರಣೆಯನ್ನು ಸಿಂಕ್ರೊನೈಸ್ ಮಾಡಲು ತುಂಬಾ ಅನುಕೂಲಕರ ಅಂಶವಾಗಿದೆ. ಒಂದು ವಹಿವಾಟು ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಸ್ಥಿತಿಯನ್ನು ಬದಲಾಯಿಸುವ ನೆಲೆಯಿಂದ ಪಡೆಯಲು ನಿರ್ವಹಿಸಿದರೆ, ಸಮಾನಾಂತರವಾಗಿ ಯಾವುದೇ ವಹಿವಾಟು ಮತ್ತೊಂದು ಬದಲಾವಣೆಗೆ ಅದೇ ಸ್ಥಿತಿಯನ್ನು ಪಡೆಯಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ ಮತ್ತು ಮೊದಲ ವಹಿವಾಟು ಪೂರ್ಣಗೊಂಡ ನಂತರ, ಎರಡನೆಯದು ಈಗಾಗಲೇ ಬದಲಾದ ಸ್ಥಿತಿಯನ್ನು ಸ್ವೀಕರಿಸುವ ಭರವಸೆ ಇದೆ.

DBMS ಬದಿಯಲ್ಲಿ ನಿರಾಶಾವಾದಿ ಬೀಗಗಳನ್ನು ಬಳಸಿ, ನಾವು ಎಲ್ಲಾ ಅಗತ್ಯ ಅವಶ್ಯಕತೆಗಳನ್ನು ಪೂರೈಸುತ್ತೇವೆ ಎಸಿಐಡಿ, ಮತ್ತು ಚಾಲನೆಯಲ್ಲಿರುವ ನಿದರ್ಶನಗಳ ಸಂಖ್ಯೆಯನ್ನು ಹೆಚ್ಚಿಸುವ ಮೂಲಕ ವ್ಯವಹಾರ ತರ್ಕದೊಂದಿಗೆ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅಳೆಯುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಸಹ ಉಳಿಸಿಕೊಳ್ಳುತ್ತದೆ.

ಆದಾಗ್ಯೂ, ನಿರಾಶಾವಾದಿ ಲಾಕ್‌ಗಳು ನಮಗೆ ಡೆಡ್‌ಲಾಕ್‌ಗಳಿಂದ ಬೆದರಿಕೆ ಹಾಕುತ್ತವೆ, ಅಂದರೆ ವ್ಯಾಪಾರದ ತರ್ಕದಲ್ಲಿನ ಕೆಲವು ಅಸಾಧಾರಣ ಪ್ರಕರಣಗಳಲ್ಲಿ ಡೆಡ್‌ಲಾಕ್‌ಗಳು ಸಂಭವಿಸಿದಲ್ಲಿ ನವೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಮಾಡಿ ಇನ್ನೂ ಕೆಲವು ಸಮಂಜಸವಾದ ಕಾಲಾವಧಿಗೆ ಸೀಮಿತವಾಗಿರಬೇಕು.

ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಪ್ರಾರಂಭದ ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಮತ್ತೊಂದು ಸಮಸ್ಯೆಯಾಗಿದೆ. ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಯಾವುದೇ ನಿದರ್ಶನವಿಲ್ಲದಿದ್ದರೂ, ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಯಾವುದೇ ಸ್ಥಿತಿಯಿಲ್ಲ, ಆದ್ದರಿಂದ ವಿವರಿಸಿದ ವಿಧಾನವು ಕಾರ್ಯನಿರ್ವಹಿಸುವುದಿಲ್ಲ. ನಿರ್ದಿಷ್ಟ ವ್ಯಾಪ್ತಿಯಲ್ಲಿ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ನಿದರ್ಶನದ ಅನನ್ಯತೆಯನ್ನು ನೀವು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಬೇಕಾದರೆ, ಪ್ರಕ್ರಿಯೆಯ ವರ್ಗ ಮತ್ತು ಅನುಗುಣವಾದ ವ್ಯಾಪ್ತಿಗೆ ಸಂಬಂಧಿಸಿದ ಕೆಲವು ರೀತಿಯ ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಆಬ್ಜೆಕ್ಟ್ ನಿಮಗೆ ಅಗತ್ಯವಿರುತ್ತದೆ. ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು, ಬಾಹ್ಯ ಸೇವೆಯ ಮೂಲಕ URI ಫಾರ್ಮ್ಯಾಟ್‌ನಲ್ಲಿ ಕೀಲಿಯಿಂದ ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಅನಿಯಂತ್ರಿತ ಸಂಪನ್ಮೂಲವನ್ನು ಲಾಕ್ ಮಾಡಲು ನಮಗೆ ಅನುಮತಿಸುವ ವಿಭಿನ್ನ ಲಾಕಿಂಗ್ ಕಾರ್ಯವಿಧಾನವನ್ನು ನಾವು ಬಳಸುತ್ತೇವೆ.

ನಮ್ಮ ಉದಾಹರಣೆಗಳಲ್ಲಿ, InitialPlayer ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಯು ಘೋಷಣೆಯನ್ನು ಒಳಗೊಂಡಿದೆ

uniqueConstraint = UniqueConstraints.singleton

ಆದ್ದರಿಂದ, ಲಾಗ್ ಅನುಗುಣವಾದ ಕೀಲಿಯ ಲಾಕ್ ಅನ್ನು ತೆಗೆದುಕೊಳ್ಳುವ ಮತ್ತು ಬಿಡುಗಡೆ ಮಾಡುವ ಬಗ್ಗೆ ಸಂದೇಶಗಳನ್ನು ಒಳಗೊಂಡಿದೆ. ಇತರ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳಿಗೆ ಅಂತಹ ಯಾವುದೇ ಸಂದೇಶಗಳಿಲ್ಲ: ಅನನ್ಯ ನಿರ್ಬಂಧವನ್ನು ಹೊಂದಿಸಲಾಗಿಲ್ಲ.

ನಿರಂತರ ಸ್ಥಿತಿಯೊಂದಿಗೆ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳ ತೊಂದರೆಗಳು

ಕೆಲವೊಮ್ಮೆ ನಿರಂತರ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿರುವುದು ಸಹಾಯ ಮಾಡುತ್ತದೆ, ಆದರೆ ನಿಜವಾಗಿಯೂ ಅಭಿವೃದ್ಧಿಗೆ ಅಡ್ಡಿಯಾಗುತ್ತದೆ.
ವ್ಯಾಪಾರ ತರ್ಕ ಮತ್ತು/ಅಥವಾ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಮಾದರಿಯಲ್ಲಿ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಬೇಕಾದಾಗ ಸಮಸ್ಯೆಗಳು ಪ್ರಾರಂಭವಾಗುತ್ತವೆ. ಅಂತಹ ಪ್ರತಿಯೊಂದು ಬದಲಾವಣೆಯು ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಗಳ ಹಳೆಯ ಸ್ಥಿತಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಅನೇಕ ಲೈವ್ ನಿದರ್ಶನಗಳಿದ್ದರೆ, ಹೊಂದಾಣಿಕೆಯಾಗದ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡುವುದು ಬಹಳಷ್ಟು ತೊಂದರೆಗಳನ್ನು ಉಂಟುಮಾಡಬಹುದು, ಇದು jBPM ಅನ್ನು ಬಳಸುವಾಗ ನಾವು ಆಗಾಗ್ಗೆ ಎದುರಿಸುತ್ತೇವೆ.

ಬದಲಾವಣೆಗಳ ಆಳವನ್ನು ಅವಲಂಬಿಸಿ, ನೀವು ಎರಡು ರೀತಿಯಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸಬಹುದು:

  1. ಹಳೆಯದಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗದ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡದಂತೆ ಹೊಸ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಪ್ರಕಾರವನ್ನು ರಚಿಸಿ ಮತ್ತು ಹೊಸ ನಿದರ್ಶನಗಳನ್ನು ಪ್ರಾರಂಭಿಸುವಾಗ ಹಳೆಯದಕ್ಕೆ ಬದಲಾಗಿ ಅದನ್ನು ಬಳಸಿ. ಹಳೆಯ ಪ್ರತಿಗಳು "ಮೊದಲಿನಂತೆ" ಕೆಲಸ ಮಾಡುವುದನ್ನು ಮುಂದುವರಿಸುತ್ತವೆ;
  2. ವ್ಯಾಪಾರ ತರ್ಕವನ್ನು ನವೀಕರಿಸುವಾಗ ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳ ನಿರಂತರ ಸ್ಥಿತಿಯನ್ನು ಸ್ಥಳಾಂತರಿಸಿ.

ಮೊದಲ ಮಾರ್ಗವು ಸರಳವಾಗಿದೆ, ಆದರೆ ಅದರ ಮಿತಿಗಳು ಮತ್ತು ಅನಾನುಕೂಲಗಳನ್ನು ಹೊಂದಿದೆ, ಉದಾಹರಣೆಗೆ:

  • ಅನೇಕ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆ ಮಾದರಿಗಳಲ್ಲಿ ವ್ಯಾಪಾರ ತರ್ಕದ ನಕಲು, ವ್ಯಾಪಾರ ತರ್ಕದ ಪರಿಮಾಣವನ್ನು ಹೆಚ್ಚಿಸುವುದು;
  • ಸಾಮಾನ್ಯವಾಗಿ ಹೊಸ ವ್ಯವಹಾರ ತರ್ಕಕ್ಕೆ ತಕ್ಷಣದ ಪರಿವರ್ತನೆಯ ಅಗತ್ಯವಿರುತ್ತದೆ (ಏಕೀಕರಣ ಕಾರ್ಯಗಳ ವಿಷಯದಲ್ಲಿ - ಬಹುತೇಕ ಯಾವಾಗಲೂ);
  • ಯಾವ ಹಂತದಲ್ಲಿ ಹಳೆಯ ಮಾದರಿಗಳನ್ನು ಅಳಿಸಬಹುದು ಎಂದು ಡೆವಲಪರ್‌ಗೆ ತಿಳಿದಿಲ್ಲ.

ಆಚರಣೆಯಲ್ಲಿ ನಾವು ಎರಡೂ ವಿಧಾನಗಳನ್ನು ಬಳಸುತ್ತೇವೆ, ಆದರೆ ನಮ್ಮ ಜೀವನವನ್ನು ಸುಲಭಗೊಳಿಸಲು ಹಲವಾರು ನಿರ್ಧಾರಗಳನ್ನು ಮಾಡಿದ್ದೇವೆ:

  • ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ, ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಯ ನಿರಂತರ ಸ್ಥಿತಿಯನ್ನು ಸುಲಭವಾಗಿ ಓದಬಲ್ಲ ಮತ್ತು ಸುಲಭವಾಗಿ ಸಂಸ್ಕರಿಸಿದ ರೂಪದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ: JSON ಫಾರ್ಮ್ಯಾಟ್ ಸ್ಟ್ರಿಂಗ್‌ನಲ್ಲಿ. ಇದು ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ಮತ್ತು ಬಾಹ್ಯವಾಗಿ ವಲಸೆಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಅನುಮತಿಸುತ್ತದೆ. ಕೊನೆಯ ಉಪಾಯವಾಗಿ, ನೀವು ಅದನ್ನು ಹಸ್ತಚಾಲಿತವಾಗಿ ಸರಿಪಡಿಸಬಹುದು (ಡೀಬಗ್ ಮಾಡುವ ಸಮಯದಲ್ಲಿ ಅಭಿವೃದ್ಧಿಯಲ್ಲಿ ವಿಶೇಷವಾಗಿ ಉಪಯುಕ್ತವಾಗಿದೆ);
  • ಏಕೀಕರಣ ವ್ಯವಹಾರ ತರ್ಕವು ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳ ಹೆಸರನ್ನು ಬಳಸುವುದಿಲ್ಲ, ಆದ್ದರಿಂದ ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಭಾಗವಹಿಸುವ ಪ್ರಕ್ರಿಯೆಗಳಲ್ಲಿ ಒಂದನ್ನು ಹೊಸ ಹೆಸರಿನೊಂದಿಗೆ ಹೊಸದರೊಂದಿಗೆ ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿದೆ (ಉದಾಹರಣೆಗೆ, "InitialPlayerV2"). ಸಂದೇಶ ಮತ್ತು ಸಿಗ್ನಲ್ ಹೆಸರುಗಳ ಮೂಲಕ ಬೈಂಡಿಂಗ್ ಸಂಭವಿಸುತ್ತದೆ;
  • ಪ್ರಕ್ರಿಯೆಯ ಮಾದರಿಯು ಆವೃತ್ತಿ ಸಂಖ್ಯೆಯನ್ನು ಹೊಂದಿದೆ, ನಾವು ಈ ಮಾದರಿಗೆ ಹೊಂದಾಣಿಕೆಯಾಗದ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಿದರೆ ನಾವು ಅದನ್ನು ಹೆಚ್ಚಿಸುತ್ತೇವೆ ಮತ್ತು ಪ್ರಕ್ರಿಯೆಯ ನಿದರ್ಶನದ ಸ್ಥಿತಿಯೊಂದಿಗೆ ಈ ಸಂಖ್ಯೆಯನ್ನು ಉಳಿಸಲಾಗುತ್ತದೆ;
  • ಪ್ರಕ್ರಿಯೆಯ ನಿರಂತರ ಸ್ಥಿತಿಯನ್ನು ಡೇಟಾಬೇಸ್‌ನಿಂದ ಮೊದಲು ಅನುಕೂಲಕರ ವಸ್ತು ಮಾದರಿಗೆ ಓದಲಾಗುತ್ತದೆ, ಮಾದರಿ ಆವೃತ್ತಿ ಸಂಖ್ಯೆ ಬದಲಾಗಿದ್ದರೆ ವಲಸೆ ಕಾರ್ಯವಿಧಾನವು ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ;
  • ವಲಸೆಯ ಕಾರ್ಯವಿಧಾನವನ್ನು ವ್ಯಾಪಾರ ತರ್ಕದ ಪಕ್ಕದಲ್ಲಿ ಇರಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಡೇಟಾಬೇಸ್‌ನಿಂದ ಅದನ್ನು ಮರುಸ್ಥಾಪಿಸುವ ಸಮಯದಲ್ಲಿ ವ್ಯವಹಾರ ಪ್ರಕ್ರಿಯೆಯ ಪ್ರತಿಯೊಂದು ನಿದರ್ಶನಕ್ಕೂ "ಸೋಮಾರಿ" ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ;
  • ನೀವು ಎಲ್ಲಾ ಪ್ರಕ್ರಿಯೆಯ ನಿದರ್ಶನಗಳ ಸ್ಥಿತಿಯನ್ನು ತ್ವರಿತವಾಗಿ ಮತ್ತು ಸಿಂಕ್ರೊನಸ್ ಆಗಿ ಸ್ಥಳಾಂತರಿಸಬೇಕಾದರೆ, ಹೆಚ್ಚು ಕ್ಲಾಸಿಕ್ ಡೇಟಾಬೇಸ್ ವಲಸೆ ಪರಿಹಾರಗಳನ್ನು ಬಳಸಲಾಗುತ್ತದೆ, ಆದರೆ ನೀವು JSON ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಬೇಕು.

ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳಿಗೆ ನಿಮಗೆ ಇನ್ನೊಂದು ಚೌಕಟ್ಟು ಬೇಕೇ?

ಲೇಖನದಲ್ಲಿ ವಿವರಿಸಿದ ಪರಿಹಾರಗಳು ನಮ್ಮ ಜೀವನವನ್ನು ಗಮನಾರ್ಹವಾಗಿ ಸರಳೀಕರಿಸಲು, ಅಪ್ಲಿಕೇಶನ್ ಅಭಿವೃದ್ಧಿ ಮಟ್ಟದಲ್ಲಿ ಪರಿಹರಿಸಲಾದ ಸಮಸ್ಯೆಗಳ ವ್ಯಾಪ್ತಿಯನ್ನು ವಿಸ್ತರಿಸಲು ಮತ್ತು ವ್ಯವಹಾರ ತರ್ಕವನ್ನು ಸೂಕ್ಷ್ಮ ಸೇವೆಗಳಾಗಿ ಬೇರ್ಪಡಿಸುವ ಕಲ್ಪನೆಯನ್ನು ಹೆಚ್ಚು ಆಕರ್ಷಕವಾಗಿಸಲು ನಮಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಟ್ಟವು. ಇದನ್ನು ಸಾಧಿಸಲು, ಬಹಳಷ್ಟು ಕೆಲಸಗಳನ್ನು ಮಾಡಲಾಗಿದೆ, ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳಿಗೆ ಅತ್ಯಂತ "ಹಗುರ" ಚೌಕಟ್ಟನ್ನು ರಚಿಸಲಾಗಿದೆ, ಜೊತೆಗೆ ವ್ಯಾಪಕ ಶ್ರೇಣಿಯ ಅಪ್ಲಿಕೇಶನ್ ಸಮಸ್ಯೆಗಳ ಸಂದರ್ಭದಲ್ಲಿ ಗುರುತಿಸಲಾದ ಸಮಸ್ಯೆಗಳನ್ನು ಪರಿಹರಿಸಲು ಸೇವಾ ಘಟಕಗಳನ್ನು ರಚಿಸಲಾಗಿದೆ. ಈ ಫಲಿತಾಂಶಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಮತ್ತು ಸಾಮಾನ್ಯ ಘಟಕಗಳ ಅಭಿವೃದ್ಧಿಯನ್ನು ಉಚಿತ ಪರವಾನಗಿ ಅಡಿಯಲ್ಲಿ ಮುಕ್ತ ಪ್ರವೇಶವನ್ನು ಮಾಡಲು ನಾವು ಬಯಸುತ್ತೇವೆ. ಇದಕ್ಕೆ ಸ್ವಲ್ಪ ಪ್ರಯತ್ನ ಮತ್ತು ಸಮಯ ಬೇಕಾಗುತ್ತದೆ. ಅಂತಹ ಪರಿಹಾರಗಳ ಬೇಡಿಕೆಯನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ನಮಗೆ ಹೆಚ್ಚುವರಿ ಪ್ರೋತ್ಸಾಹವಾಗಬಹುದು. ಪ್ರಸ್ತಾವಿತ ಲೇಖನದಲ್ಲಿ, ಚೌಕಟ್ಟಿನ ಸಾಮರ್ಥ್ಯಗಳಿಗೆ ಬಹಳ ಕಡಿಮೆ ಗಮನವನ್ನು ನೀಡಲಾಗುತ್ತದೆ, ಆದರೆ ಅವುಗಳಲ್ಲಿ ಕೆಲವು ಪ್ರಸ್ತುತಪಡಿಸಿದ ಉದಾಹರಣೆಗಳಿಂದ ಗೋಚರಿಸುತ್ತವೆ. ನಾವು ನಮ್ಮ ಚೌಕಟ್ಟನ್ನು ಪ್ರಕಟಿಸಿದರೆ, ಪ್ರತ್ಯೇಕ ಲೇಖನವನ್ನು ಅದಕ್ಕೆ ಮೀಸಲಿಡಲಾಗುತ್ತದೆ. ಈ ಮಧ್ಯೆ, ಪ್ರಶ್ನೆಗೆ ಉತ್ತರಿಸುವ ಮೂಲಕ ನೀವು ಸ್ವಲ್ಪ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ನೀಡಿದರೆ ನಾವು ಕೃತಜ್ಞರಾಗಿರುತ್ತೇವೆ:

ನೋಂದಾಯಿತ ಬಳಕೆದಾರರು ಮಾತ್ರ ಸಮೀಕ್ಷೆಯಲ್ಲಿ ಭಾಗವಹಿಸಬಹುದು. ಸೈನ್ ಇನ್ ಮಾಡಿ, ದಯವಿಟ್ಟು.

ವ್ಯಾಪಾರ ಪ್ರಕ್ರಿಯೆಗಳಿಗೆ ನಿಮಗೆ ಇನ್ನೊಂದು ಚೌಕಟ್ಟು ಬೇಕೇ?

  • 18,8%ಹೌದು, ನಾನು ಬಹಳ ಸಮಯದಿಂದ ಅಂತಹದನ್ನು ಹುಡುಕುತ್ತಿದ್ದೇನೆ

  • 12,5%ನಿಮ್ಮ ಅನುಷ್ಠಾನದ ಕುರಿತು ಇನ್ನಷ್ಟು ತಿಳಿದುಕೊಳ್ಳಲು ನಾನು ಆಸಕ್ತಿ ಹೊಂದಿದ್ದೇನೆ, ಅದು ಉಪಯುಕ್ತವಾಗಬಹುದು2

  • 6,2%ನಾವು ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಚೌಕಟ್ಟುಗಳಲ್ಲಿ ಒಂದನ್ನು ಬಳಸುತ್ತೇವೆ, ಆದರೆ 1 ಅನ್ನು ಬದಲಿಸುವ ಬಗ್ಗೆ ಯೋಚಿಸುತ್ತಿದ್ದೇವೆ

  • 18,8%ನಾವು ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಚೌಕಟ್ಟುಗಳಲ್ಲಿ ಒಂದನ್ನು ಬಳಸುತ್ತೇವೆ, ಎಲ್ಲವೂ ಉತ್ತಮವಾಗಿದೆ3

  • 18,8%ನಾವು ಚೌಕಟ್ಟು 3 ಇಲ್ಲದೆ ನಿರ್ವಹಿಸುತ್ತೇವೆ

  • 25,0%ನಿಮ್ಮದನ್ನು ಬರೆಯಿರಿ 4

16 ಬಳಕೆದಾರರು ಮತ ಹಾಕಿದ್ದಾರೆ. 7 ಬಳಕೆದಾರರು ದೂರ ಉಳಿದಿದ್ದಾರೆ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ