জাভা - জেপিএ - @ সংস্করণ টীকা


118

@Versionজেপিএতে টিকা কীভাবে কাজ করে ?

আমি বিভিন্ন উত্তর পেয়েছি যার নির্যাসটি নিম্নরূপ:

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

তবে কীভাবে এটি কাজ করে আমি এখনও নিশ্চিত নই।


নিম্নলিখিত লাইন থেকে হিসাবে:

আপনার সংস্করণ ক্ষেত্রগুলি অপরিবর্তনীয় বিবেচনা করা উচিত। ক্ষেত্রের মান পরিবর্তন করার ফলে অপরিবর্তিত ফলাফল রয়েছে।

এর অর্থ কি আমাদের সংস্করণ ক্ষেত্রটি হিসাবে ঘোষণা করা উচিত final?


1
সকল এটা আছে চেক / আপডেট প্রত্যেক আপডেটে ক্যোয়ারীতে সংস্করণ: UPDATE myentity SET mycolumn = 'new value', version = version + 1 WHERE version = [old.version]। যদি কেউ রেকর্ডটি আপডেট করে old.versionথাকে তবে ডিবিতে আর কোনওটির সাথে আর মেলে না এবং যেখানে ক্লজ আপডেটটি হওয়া থেকে বিরত রাখবে। 'সারিগুলি আপডেট করা' হবে 0, যা জেপিএ সনাক্ত করতে পারে যে উপসংহারে সিদ্ধান্ত নেওয়া হয়েছিল যে একযোগে পরিবর্তন হয়েছে।
স্টিজন ডি উইট

উত্তর:


189

তবে এখনও আমি নিশ্চিত না যে এটি কীভাবে কাজ করে?

ধরা যাক কোনও সত্তার MyEntityএকটি টীকাযুক্ত versionসম্পত্তি রয়েছে:

@Entity
public class MyEntity implements Serializable {    

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @Version
    private Long version;

    //...
}

আপডেটে, এর সাথে মন্তব্য করা ক্ষেত্রটি বাড়ানো @Versionহবে এবং ধারাটিতে যুক্ত করা হবে WHERE, এরকম কিছু:

UPDATE MYENTITY SET ..., VERSION = VERSION + 1 WHERE ((ID = ?) AND (VERSION = ?))

যদি WHEREধারাটি কোনও রেকর্ডের সাথে মেলে ব্যর্থ হয় (কারণ একই সত্তা ইতিমধ্যে অন্য থ্রেড দ্বারা আপডেট করা হয়েছে), তবে অধ্যবসায় সরবরাহকারী একটি নিক্ষেপ করবে OptimisticLockException

এর অর্থ কি এই যে আমাদের সংস্করণ ক্ষেত্রটি চূড়ান্ত হিসাবে ঘোষণা করা উচিত

না তবে আপনি সেটারটিকে সুরক্ষিত হিসাবে বিবেচনা করতে পারেন কারণ আপনি এটি কল করার কথা না।


5
কোডটির এই টুকরোটির সাথে আমি একটি নাল পয়েন্টার ব্যতিক্রম পেয়েছি, কারণ লংটি নাল হিসাবে শুরু করে, সম্ভবত 0L দিয়ে এক্সপ্লিজিটালভাবে আরম্ভ করা উচিত।
মার্কাস

2
এটিতে স্বয়ং-আনবক্সিং longবা কেবল longValue()এটির কল করার উপর নির্ভর করবেন না । আপনার স্পষ্টত nullচেক দরকার । স্পষ্টভাবে এটি নিজেকে আরম্ভ করা হচ্ছে আমি এই করবো না কারণ এই ক্ষেত্রটি ওআরএম সরবরাহকারী দ্বারা পরিচালিত হওয়ার কথা। আমি মনে করি এটি 0Lপ্রথমে ডিবিতে প্রবেশ করানোতে সেট আপ হয়ে গেছে, সুতরাং এটি যদি সেট করে nullথাকে তবে আপনাকে এই রেকর্ডটি এখনও অব্যাহত রাখা হয়নি।
স্টিজন ডি উইট

এটি কি একাধিকবার সত্তা তৈরি করার চেষ্টা করার চেষ্টা করবে? আমি বোঝাতে চাইছি একটি জেএমএস বিষয় বার্তা কোনও সত্তা তৈরির সূত্রপাত করে এবং কোনও অ্যাপ্লিকেশন বার্তা শোনার একাধিক উদাহরণ রয়েছে। আমি কেবল অনন্য সীমাবদ্ধতা লঙ্ঘন ত্রুটি এড়াতে চাই ..
মনু

দুঃখিত, আমি বুঝতে পারি যে এটি একটি পুরানো থ্রেড, তবে @ সংস্করণ কি ক্লাস্টারযুক্ত পরিবেশে নোংরা ক্যাশে বিবেচনা করে?
শান ইয়ন স্মিথ

3
যদি স্প্রিং ডেটা জেপিএ ব্যবহার করা হয় তবে ক্ষেত্রের জন্য আদিমতার Longচেয়ে একটি মোড়ক ব্যবহার করা ভাল । সত্তাটি যদি নতুন হয় (সংস্করণটি নাল হওয়ায় নির্দেশিত) তবে স্প্রিং কল করবে । তবে সংস্করণটির যদি কোনও মান থাকে তবে এটি কল করবে । এ কারণেই কোনও সংস্করণ ক্ষেত্র যা মোড়ক প্রকার হিসাবে ঘোষিত হয়েছে তা অবিচ্ছিন্ন করে ছেড়ে দেওয়া উচিত। long@VersionSimpleJpaRepository.save(entity)em.persist(entity)em.merge(entity)
rdguam

33

যদিও @ পাসল উত্তরটি পুরোপুরি বৈধ, তবে আমার অভিজ্ঞতা থেকে আমি নীচের কোডটি আশাবাদী লকিংয়ে সহায়তা করতে সহায়ক বলে মনে করি:

@Entity
public class MyEntity implements Serializable {    
    // ...

    @Version
    @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
    private long version = 0L;

    // ...
}

কেন? কারণ:

  1. আশাবাদী লকিং কাজ করবে নাফিল্ডটি @Versionদুর্ঘটনাক্রমে সেট করা থাকলেnull
  2. যেহেতু এই বিশেষ ক্ষেত্রটি অবশ্যই অবজেক্টের ব্যবসায়িক সংস্করণ নয়, একটি বিভ্রান্তিকরতা এড়ানোর জন্য, আমি এই ক্ষেত্রটির optlockপরিবর্তে এর চেয়ে ভালো কিছুতে নামকরণ পছন্দ করি version

অ্যাপ্লিকেশনটি ডাটাবেসে ডেটা forোকানোর জন্য কেবল জেপিএ ব্যবহার করে কিনা তা প্রথম পয়েন্টের বিষয়টি বিবেচনা করে না , কারণ জেপিএ বিক্রেতার তৈরির সময় ক্ষেত্রের 0জন্য প্রয়োগ করবে @version। তবে প্রায় সর্বদা প্লেইন এসকিউএল স্টেটমেন্টগুলিও ব্যবহৃত হয় (কমপক্ষে ইউনিট এবং ইন্টিগ্রেশন পরীক্ষার সময়)।


আমি এটিকে u_lmod(ব্যবহারকারী সর্বশেষ সংশোধিত) বলি যেখানে ব্যবহারকারী কোনও মানবিক বা সংজ্ঞায়িত (স্বয়ংক্রিয়) প্রক্রিয়া / সত্তা / অ্যাপ্লিকেশনu_lmod_id হতে পারে (সুতরাং অতিরিক্তভাবে সংরক্ষণ করাও বোধগম্য হতে পারে)। (এটি আমার দৃষ্টিতে খুব বেসিক ব্যবসায়-মেটা-গুণাবলী)। এটি ইউটিসিতে সাধারণত তারিখ (টিআইএম) (অর্থাত্ ইনফোস ... মিলিস প্রায় হিসাবে) সংরক্ষণ করে থাকে (যদি সম্পাদকের টাইমজোন "অবস্থান" টাইমজোন দিয়ে সংরক্ষণ করা গুরুত্বপূর্ণ) to অতিরিক্তভাবে ডিডাব্লুএইচ সিঙ্ক দৃশ্যের জন্য খুব দরকারী।
Andreas Dietrich

7
আমি মনে করি একটি দীর্ঘ জাভা টাইপের সাথে মেলে একটি পূর্ণসংখ্যার পরিবর্তে বিগিন্ট ডিবি টাইপ ব্যবহার করা উচিত।
দিমিত্রি

শুভ পয়েন্ট দিমিত্রি, ধন্যবাদ, যদিও এটি যখন আইএমএইচওর সংস্করণ করার কথা আসে তখন তা আসলেই কিছু যায় আসে না।
জি ডমেকি

9

প্রতিটি সময় ডাটাবেসে কোনও সত্তা আপডেট করা হলে সংস্করণ ক্ষেত্র একের সাথে বাড়ানো হবে। ডাটাবেসে সত্তা আপডেট করে এমন প্রতিটি ক্রিয়াকলাপ সংযুক্ত হবেWHERE version = VERSION_THAT_WAS_LOADED_FROM_DATABASE তার ক্যোয়ারিতে ।

আপনার ক্রিয়াকলাপের প্রভাবিত সারিগুলি পরীক্ষা করে জেপিএ কাঠামোটি নিশ্চিত করতে পারে যে আপনার সত্তাটি লোড করা এবং স্থির করার মধ্যে কোনও যুগপত পরিবর্তন হয়নি কারণ কোয়েরিটি ভার্সন সংখ্যাটি যখন লোড এবং অব্যাহত রাখার মধ্যে বর্ধমানের মধ্যে বৃদ্ধি পেয়েছে তখন ডাটাবেসে আপনার সত্তাটি খুঁজে পাবে না।


JPAUpdateQuery এর মাধ্যমে নয় এটি হয় না। সুতরাং "ডাটাবেসে সত্তা আপডেট করে এমন প্রতিটি অপারেশন তার ক্যোয়ারিতে WHERE সংস্করণ = VERSION_THAT_WAS_LOADED_FROM_DATABASE যুক্ত করবে" সত্য নয়।
পেড্রো বোর্জেস

2

সংস্করণটি একবারে কেবলমাত্র একটি আপডেট নিশ্চিত করে। জেপিএ সরবরাহকারী সংস্করণটি যাচাই করবে, যদি প্রত্যাশিত সংস্করণটি ইতিমধ্যে বৃদ্ধি পেয়ে থাকে তবে অন্য কেউ ইতিমধ্যে সত্তা আপডেট করে যাতে ব্যতিক্রম ছুঁড়ে যায়।

সুতরাং সত্তার মান আপডেট করা আরও সুরক্ষিত, আরও আশাবাদী।

যদি মানটি ঘন ঘন পরিবর্তিত হয়, তবে আপনি সংস্করণ ক্ষেত্রটি ব্যবহার না করার বিষয়টি বিবেচনা করতে পারেন। উদাহরণস্বরূপ "এমন একটি সত্তা যার পাল্টা ক্ষেত্র রয়েছে, যা ওয়েব পৃষ্ঠায় অ্যাক্সেস করার সময় বাড়বে"


0

শুধু আরও কিছু তথ্য যুক্ত করা হচ্ছে।

জেপিএ আপনার জন্য হুডের অধীনে সংস্করণ পরিচালনা করে, তবে আপনি যখন নিজের রেকর্ডটি আপডেট করার মাধ্যমে এটি করেন না তখন JPAUpdateClauseএ জাতীয় পরিস্থিতিতে আপনাকে ম্যানুয়ালিভাবে ক্যোয়ারিতে সংস্করণ বৃদ্ধি যুক্ত করতে হবে।

জেপিকিউএলের মাধ্যমে আপডেট করার বিষয়ে একই কথা বলা যেতে পারে, অর্থাত্ সত্তার কোনও সাধারণ পরিবর্তন নয়, তবে হাইবারনেট দ্বারা সম্পন্ন করা হলেও ডাটাবেজে আপডেট কমান্ড command

পেড্রো


3
কী JPAUpdateClause?
কার্ল রিখটার

ভাল প্রশ্ন, সহজ উত্তর: খারাপ উদাহরণ :) JPAUpdateClause কোয়েরিএসএল নির্দিষ্ট, আপনি কোডে কোনও সত্তার রাষ্ট্রকে প্রভাবিত করার বিপরীতে জেপিকিউএল সহ একটি আপডেট চালানো ভাবেন।
পেড্রো বোর্জেস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.