বসন্ত - @ লেনদেন - পটভূমিতে কী ঘটে?


334

আমি জানতে চাই যে আপনি যখন কোনও পদ্ধতির সাথে টিকা টানেন তখন আসলে কী ঘটে @Transactional? অবশ্যই, আমি জানি যে স্প্রিং একটি ট্রানজেকশনে সেই পদ্ধতিটি আবদ্ধ করবে।

তবে, আমার নিম্নলিখিত সন্দেহ আছে:

  1. শুনেছি স্প্রিং একটি প্রক্সি ক্লাস তৈরি করে ? কেউ আরও গভীরতা এ ব্যাখ্যা করতে পারেন । আসলে প্রক্সি ক্লাসে কী থাকে? প্রকৃত শ্রেণীর কি হয়? এবং আমি কীভাবে বসন্তের তৈরি প্রক্সাইড শ্রেণি দেখতে পারি
  2. আমি স্প্রিং ডক্সেও পড়েছি যে:

দ্রষ্টব্য: যেহেতু এই প্রক্রিয়া প্রক্সি ভিত্তিক, কেবলমাত্র প্রক্সি মাধ্যমে আসা 'বাহ্যিক' পদ্ধতি কলগুলি বাধা দেওয়া হবে । এর অর্থ হ'ল 'স্ব-আহ্বান', অর্থাত্ টার্গেট অবজেক্টের মধ্যে এমন একটি পদ্ধতি যা টার্গেট অবজেক্টের অন্য কোনও পদ্ধতিকে ডাকে, রানটাইমের সময় প্রকৃত লেনদেনের দিকে পরিচালিত করে না যদিও অনুরোধকৃত পদ্ধতিটি চিহ্নিত থাকলেও @Transactional!

সূত্র: http://static.springsource.org/spring/docs/2.0.x/references/transaction.html

কেন কেবল বহিরাগত পদ্ধতির কলগুলি লেনদেনের অধীনে থাকবে এবং স্ব-অনুরোধ পদ্ধতিগুলি নয়?


2
প্রাসঙ্গিক আলোচনা এখানে: stackoverflow.com/questions/3120143/...
dma_k

উত্তর:


255

এটি একটি বড় বিষয়। স্প্রিং রেফারেন্স ডক এটিতে একাধিক অধ্যায় নিবেদিত করে। আমি স্পষ্ট-ওরিয়েন্টেড প্রোগ্রামিং এবং লেনদেনের বিষয়গুলি পড়ার পরামর্শ দিচ্ছি , কারণ স্প্রিংয়ের ঘোষণামূলক লেনদেন সমর্থনটি এর ভিত্তিতে এওপি ব্যবহার করে।

তবে খুব উচ্চ স্তরে, স্প্রিং ক্লাসের জন্য প্রক্সি তৈরি করে যা ক্লাসে বা সদস্যদের @ ট্রান্সজেকশনাল হিসাবে ঘোষণা করে। প্রক্সিটি বেশিরভাগ রানটাইমে অদৃশ্য। এটি বসন্তের জন্য বস্তুর প্রক্সির আগে, পরে, বা চারপাশে পদ্ধতি কলগুলির জন্য আচরণগুলি ইনজেক্ট করার একটি উপায় সরবরাহ করে। লেনদেন পরিচালনা হ'ল আচরণগুলির মধ্যে একটি উদাহরণ যা সুরক্ষা চেক। এবং লগিংয়ের মতো জিনিসগুলির জন্য আপনি নিজেরও সরবরাহ করতে পারেন। সুতরাং যখন আপনি @ ট্রান্সজেকশনাল দিয়ে কোনও পদ্ধতির টীকা দেন , তখন স্প্রিং গতিশীলভাবে এমন একটি প্রক্সি তৈরি করে যা আপনি বর্গ করছেন এমন শ্রেণীর মতো একই ইন্টারফেস (গুলি) প্রয়োগ করে। এবং যখন ক্লায়েন্টগুলি আপনার অবজেক্টে কল করে, কলগুলি বাধা দেওয়া হয় এবং প্রক্সি প্রক্রিয়াটির মাধ্যমে আচরণগুলি ইনজেকশনের ব্যবস্থা করা হয়।

ইজেবিতে লেনদেন একইভাবে, উপায় দ্বারা কাজ করে।

যেমন আপনি পর্যবেক্ষণ করেছেন, এর মাধ্যমে, প্রক্সি প্রক্রিয়াটি কেবল তখনই কাজ করে যখন কোনও বাহ্যিক বস্তুর কল আসে। আপনি যখন অবজেক্টের মধ্যে একটি অভ্যন্তরীণ কল করেন, আপনি প্রক্সিটিকে বাইপাস করে " এই " রেফারেন্সের মাধ্যমে সত্যিই কল করছেন । তবে সমস্যাটি ঘিরে কাজ করার উপায় রয়েছে। আমি এই ফোরাম পোস্টে একটি পদ্ধতির ব্যাখ্যা করেছি যেখানে আমি রানটাইমে "স্ব-রেফারেন্সিং" ক্লাসে প্রক্সিটির একটি উদাহরণ ইনজেক্ট করতে একটি বিয়ানফ্যাক্ট্রিপোস্টপ্রসেসর ব্যবহার করি । এই রেফারেন্সটি আমি " me " নামক একটি সদস্য ভেরিয়েবলে সংরক্ষণ করি । তারপরে যদি আমাকে অভ্যন্তরীণ কলগুলি করতে হয় যার জন্য থ্রেডের লেনদেনের স্থিতির পরিবর্তনের প্রয়োজন হয়, আমি প্রক্সিটির মাধ্যমে কলটি পরিচালনা করি (যেমন " me.someMethod ()"।) ফোরাম পোস্টটি আরও বিশদে বিশদ ব্যাখ্যা করেছে Note দ্রষ্টব্য যে BeanFactoryPostProcessor কোডটি এখন একটু আলাদা হবে, কারণ এটি স্প্রিং 1.x টাইমফ্রেমে ফিরে লেখা হয়েছিল। তবে আশা করি এটি আপনাকে একটি ধারণা দেয়। আমার একটি আপডেট সংস্করণ রয়েছে যে আমি সম্ভবত উপলব্ধ করতে পারে।


4
>> প্রক্সিটি বেশিরভাগ রানটাইমে অদৃশ্য হয় ওহ !! আমি তাদের দেখার জন্য আগ্রহী :) বিশ্রাম .. আপনার উত্তরটি খুব ব্যাপক ছিল comprehensive এই দ্বিতীয় বার আপনি আমাকে সাহায্য করছেন..সকল সহায়তার জন্য ধন্যবাদ।
শিখর

17
সমস্যা নেই. আপনি কোনও ডিবাগারের সাথে পদক্ষেপ নিলে আপনি প্রক্সি কোডটি দেখতে পাবেন। এটি সম্ভবত সবচেয়ে সহজ উপায়। কোন যাদু নেই; তারা বসন্ত প্যাকেজগুলির মধ্যে কেবল ক্লাস।
রব এইচ

যদি পদ্ধতি যা @Transaction টীকা বসন্ত একটি ইন্টারফেস বাস্তবায়ন করছে transactionalisation উদ্বুদ্ধ করতে গতিশীল প্রক্সি এপিআই ব্যবহার করবে এবং হয়েছে না প্রক্সি ব্যবহার করুন। আমি আমার লেনদেনের ক্লাসগুলি যে কোনও ক্ষেত্রে ইন্টারফেস প্রয়োগ করতে পছন্দ করি।
মাইকেল উইলস 14

1
আমি "আমার" স্কিমটিও পেয়েছি (আমার মনে হয় এমনভাবে তারের সুস্পষ্ট ওয়্যারিং ব্যবহার করে) তবে আমি মনে করি আপনি যদি সেভাবে এটি করেন তবে আপনি সম্ভবত রিফ্যাক্টরিংয়ের চেয়ে আরও ভাল better করতে হবে. তবে হ্যাঁ, এটি কখনও কখনও খুব বিশ্রী হতে পারে!
ডোনাল ফেলো

2
2019: যেহেতু এই উত্তর পুরাতন হচ্ছে, উল্লেখ ফোরাম পোস্টে আর উপলব্ধ নেই যখন যে ক্ষেত্রে বর্ণনা করবেন আপনি বস্তুর মধ্যে একটি অভ্যন্তরীণ কল করতে হবে ছাড়া , প্রক্সি বাইপাস ব্যবহারBeanFactoryPostProcessor । তবে এই উত্তরে বর্ণিত একটি (আমার মতে) খুব অনুরূপ পদ্ধতি রয়েছে: স্ট্যাকওভারফ্লো . com / a / 11277899 / 3667003 ... এবং পুরো থ্রেডে আরও সমাধান।
Z3d4s

195

যখন স্প্রিং আপনার শিম সংজ্ঞাগুলি বোঝায়, এবং @Transactionalটীকাগুলি সন্ধানের জন্য কনফিগার করা হয়েছে , এটি আপনার প্রকৃত বিনের চারপাশে এই প্রক্সি অবজেক্ট তৈরি করবে । এই প্রক্সি অবজেক্টগুলি ক্লাসের উদাহরণ যা রানটাইম সময়ে স্বয়ংক্রিয়ভাবে উত্পন্ন হয়। যখন কোনও পদ্ধতিটি আহ্বান করা হয় তখন এই প্রক্সি অবজেক্টগুলির ডিফল্ট আচরণ হ'ল "লক্ষ্য" শিমের (যেমন আপনার শিম) একই পদ্ধতিটি চাওয়া।

যাইহোক, প্রক্সিগুলি ইন্টারসেপ্টরগুলির সাথে সরবরাহ করা যেতে পারে এবং যখন এই ইন্টারসেপ্টরগুলি প্রক্সি দ্বারা আপনার টার্গেট শিমের পদ্ধতিটি আহ্বান করার আগে ডাকে। লক্ষ্যযুক্ত মটরশুটি দিয়ে মন্তব্য করা হয়েছে @Transactional, স্প্রিং একটি তৈরি করবে TransactionInterceptorএবং উত্পন্ন প্রক্সি অবজেক্টে এটি প্রেরণ করবে। সুতরাং যখন আপনি ক্লায়েন্ট কোড থেকে পদ্ধতিটি কল করবেন, আপনি প্রক্সি অবজেক্টে পদ্ধতিটি কল করছেন, যা প্রথমে অনুরোধ করে TransactionInterceptor(যা একটি লেনদেন শুরু করে) যা ফলস্বরূপ আপনার লক্ষ্য বিনের পদ্ধতিতে অনুরোধ করে। যখন অনুরোধটি শেষ হয়, TransactionInterceptorতখন লেনদেনটি করে / ফেরত দেয়। এটি ক্লায়েন্ট কোডে স্বচ্ছ।

"বাহ্যিক পদ্ধতি" জিনিস হিসাবে, যদি আপনার শিমটি তার নিজস্ব কোনও পদ্ধতির জন্য আবেদন করে, তবে এটি প্রক্সি দিয়ে তা করা হবে না। মনে রাখবেন, স্প্রিং আপনার শিমকে প্রক্সিতে জড়িয়ে দেয়, আপনার শিমের এটি কোনও জ্ঞান নেই। আপনার শিমটি কেবল "বাইরের" থেকে কলগুলি প্রক্সি দিয়ে যায়।

এটা কি সাহায্য করে?


36
> মনে রাখবেন, বসন্ত আপনার শিমকে প্রক্সিতে জড়িয়ে দেয়, আপনার শিমের কোনও জ্ঞান নেই এটি এগুলি বলেছে। কি দুর্দান্ত উত্তর। সাহায্য করার জন্যে ধন্যবাদ.
শিখর

প্রক্সি এবং ইন্টারসেপ্টরগুলির জন্য দুর্দান্ত ব্যাখ্যা। এখন আমি স্প্রিং একটি টার্গেট শিমের কলগুলিতে বাধা দেওয়ার জন্য একটি প্রক্সি অবজেক্ট বাস্তবায়ন করি। ধন্যবাদ!
ধড়গ

আমি মনে করি আপনি বসন্তের ডকুমেন্টেশনের এই চিত্রটি বর্ণনা করার চেষ্টা করছেন এবং এই চিত্রটি দেখতে আমাকে অনেক সহায়তা করে: ডকসস.স্প্রিং.আইও
ওয়েস্টার্নগান

44

ভিজ্যুয়াল ব্যক্তি হিসাবে আমি প্রক্সি প্যাটার্নের সিকোয়েন্স ডায়াগ্রামের সাথে মাপতে চাই। আপনি যদি তীরগুলি কীভাবে পড়তে না জানেন তবে আমি প্রথমটির মতো পড়ি: কার্যকর Clientকরে Proxy.method()

  1. ক্লায়েন্ট তার দৃষ্টিভঙ্গি থেকে লক্ষ্য একটি পদ্ধতি কল, এবং প্রক্সি দ্বারা নিঃশব্দে বিরত আছে
  2. যদি পূর্বের দিকটি সংজ্ঞায়িত করা হয় তবে প্রক্সি এটি কার্যকর করে
  3. তারপরে, আসল পদ্ধতি (লক্ষ্য) কার্যকর করা হয়
  4. ফিরে আসার পরে এবং নিক্ষেপ করা হ'ল returnsচ্ছিক দিকগুলি যা পদ্ধতিটি ফেরার পরে কার্যকর করা হয় এবং / অথবা পদ্ধতিটি যদি কোনও ব্যতিক্রম ছুঁড়ে দেয়
  5. এর পরে, প্রক্সি পরবর্তী দিকটি কার্যকর করে (যদি সংজ্ঞায়িত করা হয়)
  6. অবশেষে প্রক্সি কলিং ক্লায়েন্টের কাছে ফিরে আসে

প্রক্সি প্যাটার্ন সিকোয়েন্স ডায়াগ্রাম (আমাকে ছবিটির উত্সের শর্তে পোস্ট করার অনুমতি দেওয়া হয়েছিল Author লেখক: নোয়েল ওয়েস, ওয়েবসাইট: www.noelvaes.eu)


27

সবচেয়ে সহজ উত্তর:

যে কোনও পদ্ধতিতে আপনি @Transactionalলেনদেনের সীমা ঘোষণা করেন এবং পদ্ধতিটি সম্পূর্ণ হলে সীমানা শেষ হয়।

আপনি যদি জেপিএ কল ব্যবহার করছেন তবে সমস্ত কমিটগুলি এই লেনদেনের সীমানায় রয়েছে

বলুন আপনি সত্ত্বা 1, সত্তা 2 এবং সত্তা 3 সংরক্ষণ করছেন। সত্তা 3 সংরক্ষণ করার সময় একটি ব্যতিক্রম ঘটে , তারপরে এনটিই 1 এবং সত্তা 2 একই লেনদেনে আসে সুতরাং এন্টিটি 1 এবং সত্তা 2 সত্তা 3 এর সাথে রোলব্যাক হবে ।

লেনদেন:

  1. entity1.save
  2. entity2.save
  3. entity3.save

যে কোনও ব্যতিক্রমের ফলে ডিবি সহ সমস্ত জেপিএ লেনদেনের রোলব্যাক হবে tern অভ্যন্তরীণভাবে জেপিএ লেনদেনটি স্প্রিং দ্বারা ব্যবহৃত হয়।


2
"আনিয়া ব্যতিক্রমের ফলে ডিবি সহ সমস্ত জেপিএ লেনদেনের রোলব্যাক হবে" " দ্রষ্টব্য শুধুমাত্র রোলটাইম এক্সসেপশন ফলাফল রোলব্যাকে। ব্যতিক্রম চেক করা হয়েছে, এর ফলে রোলব্যাক হবে না।
অর্জুন

2

এটি দেরিতে হতে পারে তবে আমি এমন কিছু বিষয় পেলাম যা প্রক্সি সম্পর্কিত আপনার উদ্বেগকে ব্যাখ্যা করে (প্রক্সিটির মাধ্যমে আসা কেবল 'বাহ্যিক' পদ্ধতি কলগুলি বাধা দেওয়া হবে) ly

উদাহরণস্বরূপ, আপনার কাছে এমন একটি ক্লাস রয়েছে যা দেখতে এটির মতো দেখাচ্ছে

@Component("mySubordinate")
public class CoreBusinessSubordinate {

    public void doSomethingBig() {
        System.out.println("I did something small");
    }

    public void doSomethingSmall(int x){
        System.out.println("I also do something small but with an int");    
  }
}

এবং আপনার একটি দিক রয়েছে যা দেখতে এটির মতো দেখাচ্ছে:

@Component
@Aspect
public class CrossCuttingConcern {

    @Before("execution(* com.intertech.CoreBusinessSubordinate.*(..))")
    public void doCrossCutStuff(){
        System.out.println("Doing the cross cutting concern now");
    }
}

আপনি যখন এটিকে এভাবে চালিত করেন:

 @Service
public class CoreBusinessKickOff {

    @Autowired
    CoreBusinessSubordinate subordinate;

    // getter/setters

    public void kickOff() {
       System.out.println("I do something big");
       subordinate.doSomethingBig();
       subordinate.doSomethingSmall(4);
   }

}

উপরে প্রদত্ত কোডের উপরে কিকআফ কল করার ফলাফল।

I do something big
Doing the cross cutting concern now
I did something small
Doing the cross cutting concern now
I also do something small but with an int

তবে আপনি যখন আপনার কোডটি পরিবর্তন করেন

@Component("mySubordinate")
public class CoreBusinessSubordinate {

    public void doSomethingBig() {
        System.out.println("I did something small");
        doSomethingSmall(4);
    }

    public void doSomethingSmall(int x){
       System.out.println("I also do something small but with an int");    
   }
}


public void kickOff() {
  System.out.println("I do something big");
   subordinate.doSomethingBig();
   //subordinate.doSomethingSmall(4);
}

আপনি দেখুন, পদ্ধতিটি অভ্যন্তরীণভাবে অন্য পদ্ধতিটিকে কল করে যাতে এটি বাধা দেওয়া হবে না এবং আউটপুটটি এর মতো দেখায়:

I do something big
Doing the cross cutting concern now
I did something small
I also do something small but with an int

আপনি এটি করে বাই-পাস করতে পারেন

public void doSomethingBig() {
    System.out.println("I did something small");
    //doSomethingSmall(4);
    ((CoreBusinessSubordinate) AopContext.currentProxy()).doSomethingSmall(4);
}

কোড স্নিপেট থেকে নেওয়া: https://www.intertech.com/Blog/secrets-of-the-spring-aop-proxy/


0

সমস্ত বিদ্যমান উত্তর সঠিক, তবে আমি মনে করি কেবল এই জটিল বিষয়টি দিতে পারি না।

একটি বিস্তৃত, ব্যবহারিক ব্যাখ্যার জন্য আপনি এই স্প্রিং @ ট্রান্সজেকশনাল ইন-ডেপথ গাইডটিতে একবার নজর রাখতে চাইতে পারেন , যা প্রচুর কোড উদাহরণ সহ transaction 4000 ডান সরল কথায় লেনদেন পরিচালনার জন্য সর্বোত্তম চেষ্টা করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.