1. লেনদেন এবং ডেটা সঙ্গতিকতা পরিচিতি

একটি লেনদেন হল ডাটাবেস ব্যবস্থা পদ্ধতির কার্যক্রম এর একটি লজিক্যাল ইউনিট, যা এক ধাপের সিতান্তে থাকে। এই কার্যক্রমগুলি সবগুলি বা সব ব্যর্থ হয় বা একটি অথবা অধিক সেট হিসাবে চিহ্নিত হয় এবং এই ব্যবস্থাগুলি একটি অবিভাজ্য সম্পূর্ণতা হিসাবে ব্যাবস্থা করা। লেনদেনের মৌলিক মৌলিক লক্ষণগুলি অনিবার্যভাবে হল ঃ

  • এটমিসিটি: লেনদেনের সমস্ত কার্যক্রমগুলি সমপূর্ণভাবে সমাপ্ত হয় অথবা সম্পূর্ণভাবে সমাপ্ত নয়; আংশিক সমাপ্তি সম্ভব নয়।
  • সংগতি: একটি লেনদেন ব্যবস্থাকে এক সামঞ্জস্যপূর্ণ অবস্থা থেকে অন্য সামঞ্জস্যপূর্ণ অবস্থায় পাঠাতে হবে।
  • আইসোলেশন: একটি লেনদেনের ব্যবহার অন্যান্য লেনদেনগুলির প্রভাব থেকে আবর্জনা পেতে হবে, এবং একাধিক সময়কালীন লেনদেন মধ্যে ডেটা আইসোলেট থাকতে হবে।
  • টিথিরদূরী: একটি লেনদেন যখন সামর্থ্যহীন করা হয়, তখন এটির দ্বারা স্থাপিত পরিবর্তনগুলি ডাটাবেসে থাকবে।

ডেটা সঙ্গতিকতা হল একটি ডাটাবেসের একাধিক কার্যক্রমের পরে সঠিক এবং বৈধ ডেটা অবস্থা রক্ষণাবেক্ষণ। অবস্থানুযায়ী সংগতিকতা ডেটা সংগতির্ভেগে ও সিস্টেম বিফল মৌকোৎ, ডেটা সঙ্গতি বিশেষভাবে গুরুত্বপূর্ণ, এবং লেনদেনের মাধ্যমে নিশ্চিত হওয়া হল যে তথ্য সংগতি ত্রুটি পরিস্থিতিতে সংকটের মধ্যে বা সংঘটিত ঘটনার জন্য কোনও প্রভাবের না পড়ে।

2. ent ফ্রেমওয়ার্কের ওভারভিউ

ent হল একটি এন্টিটি ফ্রেমওয়ার্ক যা গো প্রোগ্রামিং ভাষায় কোডের প্রজেকশনের মাধ্যমে ডাটাবেস চালানোর জন্য টাইপ-সেফ API প্রদান করে। এটি ডাটাবেস অপারেশনগুলি আরও স্পষ্ট এবং নিরাপদ করতে সক্ষম, যেমনঃ SQL ইঞ্জেকশন এর মতো নিরাপত্তা সমস্যা এড়ানো। লেনদেন প্রসেসিং এর দৃষ্টিগোচ্ছে ent ফ্রেমওয়ার্কটি বলে দেয় প্রবল সমর্থন, যা প্রোগ্রামারদেরকে বৃহত্তর লেনদেন অপারেশন সম্পাদন করতে যোগ্য করে এবং নিশ্চিত করে যে লেনদেনের ACID গুনাঙ্গুলি মেটা হয়।

3. লেনদেন শুরু করা

3.1 ent এ লেনদেন কিভাবে শুরু করা যায়

ent ফ্রেমওয়ার্কে, নির্ধারিত কনটেক্সটে ব্যবহার করে client.Tx পদক্ষেপ দ্বারা সহজেই একটি নতুন লেনদেন আরম্ভ করা যায়, যা একটি Tx লেনদেন অবজেক্ট ফিরিয়ে দেয়। নিম্নের উদাহরণ কোড:

tx, err := client.Tx(ctx)
if err != nil {
    // লেনদেন চালাতে সময় ত্রুটি নিয়ন্ত্রণ করুন
    return fmt.Errorf("লেনদেন আরম্ভ করার সময় ত্রুটি ঘটেছে: %w", err)
}
// tx ব্যবহার করে পরবর্তী অপারেশন পারদর্শিতা বাড়ায়...

3.2 লেনদেনের মধ্যে অপারেশন পারদর্শিতা করা

যখন Tx অবজেক্টটি সফলভাবে তৈরি হয়, তখন এটি ব্যবহার করা যাবে ডাটাবেস অপারেশন সম্পাদন করার জন্য। Tx অবজেক্টে সম্পাদন সম্পাদন, মুছে ফেলা, আপডেট এবং প্রশ্না অপারেশন সম্পাদন করা হয় তারা সবই লেনদেনের অংশ হয়। নিম্নের উদাহরণ একটি ধারণা দেয়:

hub, err := tx.Group.
    Create().
    SetName("গিটহাব").
    Save(ctx)
if err != nil {
    // যদি কোনও ত্রুটি ঘটে, তবে লেনদেন ফিরিয়ে দিন
    return rollback(tx, fmt.Errorf("গোষ্ঠী তৈরি করা ব্যর্থ: %w", err))
}
// এখানে অতিরিক্ত অপারেশন যোগ করা যেতে পারে...
// লেনদন সাক্ষর করুন
tx.Commit()

4. ত্রুটি হ্যান্ডলিং এবং লেনদেনে ফিরিয়ে আনা

4.1 ত্রুটি হ্যান্ডলিং এর গুরুত্ব

ডাটাবেস সহজলভ্যভাবে বিভিন্ন ত্রুটি যেমন নেটওয়ার্ক সমস্যা, ডেটা সংঘটন, বাধ্যতামূলক অভিযোগ ইত্যাদি সম্পর্কে হতে পারে। এই ত্রুটিগুলির সঠিকভাবে নিয়ন্ত্রণ করা ডেটা সংগতিকতা বজায় রাখার জন্য অত্যন্ত গুরুত্বপূর্ণ। লেনদেনের মধ্যে, যদি কোনও অপারেশন ব্যর্থ হয়, তবে তা উল্লগ্নতা ভঙ্গ না হওয়ার জন্য লেনদেনটি ফিরিয়ে আনা প্রয়োজন।

4.2 কিভাবে ফিরিয়ে আনা হবে

ent ফ্রেমওয়ার্কে, আপনি Tx.Rollback() পদক্ষেপ ব্যবহার করে সম্পূর্ণ লেনদেন ফিরিয়ে আনতে পারেন। সাধারণত, rollback হেল্পার ফাংশনের মাধ্যমে একটি rollback ফাংশন নির্ধারণ করা হয় যেটি ফিরিয়ে আনার এবং ত্রুটি নিয়ন্ত্রণ বিধান করে, যেমন নিম্নলিখিত উদাহরণ:

func rollback(tx *ent.Tx, err error) error {
    if rerr := tx.Rollback(); rerr != nil {
        // যদি ফিরিয়ে আনা ব্যর্থ হয়, তবে মূল ত্রুটি এবং ফিউ ত্রুটি সহ প্রকাশ নিতে
        err = fmt.Errorf("%w: লেনদেন ফিরিয়ে আনার সময় ত্রুটি ঘটেছে: %v", err, rerr)
    }
    return err
}

এই rollback ফাংশনের মাধ্যমে, আমরা স্বাভাবিকভাবে ত্রুটি ও লেনদেন ফিরিয়ে আনা করতে সক্ষম হয়। এটি নিশ্চিত করে যে এর মাধ্যমে কোনও ত্রুটি

5. লেন-দেনিক ক্লায়েন্ট ব্যবহার

ব্যবহারিক প্রয়োজনে, সেনাবাহিত কোডকে দ্রুতভাবে লেন-দেনিক কোডে রূপান্তর করতে হতে পারে। এই ধরনের ক্ষেত্রে, আমরা একটি লেন-দেনিক ক্লায়েন্ট ব্যবহার করে কোডটি সহজেই মাইগ্রেট করতে পারি। নিচে দেখানো হলো যেভাবে অসময়িক লেন-দেন ক্লায়েন্ট কোডকে লেন-দেনিক কোডে রূপান্তর করতে হয়:

// এই উদাহরণে, আমরা মূল Gen ফাংশনকে একটি লেন-দেনে এনক্লোজ করি।
func WrapGen(ctx context.Context, client *ent.Client) error {
    // প্রথমে, একটি লেন-দেন সৃষ্টি করুন
    tx, err := client.Tx(ctx)
    if err != nil {
        return err
    }
    // লেন-দেনের ক্লায়েন্ট প্রাপ্ত করুন
    txClient := tx.Client()
    // মূল Gen ফাংশন প্রয়োগ করুন লেন-দেনের ক্লায়েন্ট ব্যবহার করে মূল Gen কোড পরিবর্তন করা ছাড়া
    if err := Gen(ctx, txClient); err != nil {
        // যদি কোন ত্রুটি দেখা যায়, তাহলে সে লেন-দেন ফিরিয়ে দিন
        return rollback(tx, err)
    }
    // যদি সফল হয়, তাহলে লেন-দেন সমর্থন করুন
    return tx.Commit()
}

উপরের কোডে, লেন-দেন ক্লায়েন্ট tx.Client () ব্যবহার করা হয়েছে, যা মূল Gen ফাংশনটি একটি লেন-দেনের গ্যারান্টি অধীনে প্রয়োগ করার জন্য অনুমতি দেয়। এই পদ্ধতিটি আমাদের দেওয়ান লেজিকে ন্যূনতম প্রভাবে দেওয়ার সাথে ক্ষমতাপূর্বক অসময়ি লেন-দেনিক কোডকে লেন-দেনিক কোডে প্রতিবর্তন করার সুযোগ করতে দেয়।

6. লেন-দেনের জন্য সেরা অনুশাসনাসমূহ

6.1 কলব্যাক ফাংশন দিয়া লেন-দেন পরিচালনা

যখন আমাদের কোড লজিক জটিল হয় এবং এতে একাধিক ডাটাবেজ অপারেশন শামিল হয়, তখন এই অপারেশনগুলির সেন্ট্রালাইজড পরিচালনা লেন-দেনের মধ্যে বিশেষতঃ গুরুত্বপূর্ণ হয়। নিম্নে একটি উদাহরণ দেওয়া হল কলব্যাক ফাংশনের মাধ্যমে লেন-দেনগুলি পরিচালনা করতে:

func WithTx(ctx context.Context, client *ent.Client, fn func(tx *ent.Tx) error) error {
    tx, err := client.Tx(ctx)
    if err != nil {
        return err
    }
    // সম্ভাব্য প্যানিকের স্থিতিতে যোগ করুন এবং পুনরুদ্ধার করুন
    defer func() {
        if v := recover(); v != nil {
            tx.Rollback()
            panic(v)
        }
    }()
    // প্রদত্ত কলব্যাক ফাংশনটি কল করার জন্য এই জন্য যোগ করুন লেন-দেনের লজিক প্রথম।
    if err := fn(tx); err != nil {
        // ত্রুটির ক্ষেত্রে, লেন-দেনটি ফিরিয়ে দিন
        if rerr := tx.Rollback(); rerr != nil {
            err = fmt.Errorf("%w: rolling back transaction: %v", err, rerr)
        }
        return err
    }
    // যদি ব্যবসায়িক লজিক ত্রুটি মুক্ত হয়, তাহলে লেন-দেন সমর্থন করুন
    return tx.Commit()
}

WithTx ফাংশন ব্যবহার করে ব্যবসায়িক লজিককে আবর্তন করার সময়, আমরা নিশ্চিত করতে পারি যে প্রবণতাই ত্রুটি অথবা ব্যবসায়িক লজিকের ভিতরে যদি ত্রুটি বা ব্যাধি হয়, তাহলে লেন-দেনটি ঠিকমতো হ্যান্ডেল করা হবে (বা সমর্থন করা হবে অথবা ফিরিয়ে দেওয়া হবে)।

6.2 লেন-দেন হুক ব্যবহার করা

স্কিমা হুক এবং রান-টাইম হুকের মতো, একটি সক্রিয় লেন-দেন (Tx) এ হুক নিবন্ধন করতে পারি, যা Tx.Commit বা Tx.Rollback পর ট্রিগার হবে:

func Do(ctx context.Context, client *ent.Client) error {
    tx, err := client.Tx(ctx)
    if err != nil {
        return err
    }
    tx.OnCommit(func(next ent.Committer) ent.Committer {
        return ent.CommitFunc(func(ctx context.Context, tx *ent.Tx) error {
            // লেন-দেন সমর্থন করার আগে লজিক
            err := next.Commit(ctx, tx)
            // লেন-দেন সমর্থনের পরে লজিক
            return err
        })
    })
    tx.OnRollback(func(next ent.Rollbacker) ent.Rollbacker {
        return ent.RollbackFunc(func(ctx context.Context, tx *ent.Tx) error {
            // লেন-দেন ফিরিয়ে দেওয়ার আগে লজিক
            err := next.Rollback(ctx, tx)
            // লেন-দেন ফিরিয়ে দেওয়ার পরে লজিক
            return err
        })
    })
    // অন্যান্য ব্যবসায়িক লজিক প্রয়োগ করুন
    //
    // 
    //
    return err
}

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

7. বিভিন্ন লেনদেন আইসোলেশন স্তর বোঝা

ডাটাবেস সিস্টেমে, লেনদেন আইসোলেশন স্তর নির্ধারণ করা, বিভিন্ন পারস্পরিক সমস্যা (যেমন: ডার্টি রিড, অ-রিপিটেবল রিড, এবং ফ্যান্টম রিড) প্রতিরোধ করা গুরুত্বপূর্ণ। নিম্নলিখিত কিছু মানক আইসোলেশন স্তর এবং তাদেরকে ent ফ্রেমওয়ার্কে কীভাবে নির্ধারণ করা যায়, তা নিম্নে দেওয়া হলঃ

  • READ UNCOMMITTED: সর্বনিম্ন স্তর, যাতে সংরক্ষিত না করা তথ্যের পড়াশোনা সম্ভব, যা ডার্টি রিড, অ-রিপিটেবল রিড এবং ফ্যান্টম রিডের সৃষ্টি করতে পারে।
  • READ COMMITTED: তথ্যের পড়াশোনা এবং সংরক্ষণ সুনির্দিষ্ট করা হোক, মুটো রিড তবে এখনো অ-রিপিটেবল রিড এবং ফ্যান্টম রিড সম্ভব।
  • REPEATABLE READ: একই লেনদেনে একই তথ্য পড়াশোনা করে কোন প্রযুক্তি ফলাফল উৎপন্ন করে, এবং এটি নিরন্তর ও সমতুল্য ফলাফল উৎপন্ন করে, অ-রিপিটেবল রিড তবে এখনো ফ্যান্টম রিড সম্ভব।
  • SERIALIZABLE: সবচেয়ে কঠোর আইসোলেশন স্তর, এটি দ্রুত ডার্টি রিড, অ-রিপিটেবল রিড এবং ফ্যান্টম রিড প্রতিরোধ করার চেষ্টা করে তথ্য লক করে।

ent-এ, যদি ডাটাবেস ড্রাইভার লেনদেন আইসোলেশন স্তর সেট করার সমর্থন করে, তবে এটি নিম্নে উল্লেখ করা মত নির্ধারণ করা যায়ঃ

// ট্রান্জ্যাকশন আইসোলেশন স্তর কে অনুষ্ঠিত করুন
tx, err := client.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelRepeatableRead})

ডাটা সন্তুষ্টি এবং সিস্টেম স্থিতিশীলতা নিশ্চিত করার জন্য, লেনদেন আইসোলেশন স্তর এবং তাদের ডাটাবেসে অনুপ্যুতিত অনুপ্যুতি বুঝা গুরুত্বপূর্ণ। উন্নত কার্যকলাপ সংরক্ষণ এবং পারফরম্যান্স অপটাইজেশনের জন্য ডেভেলপাররা নির্দিষ্ট অ্যাপ্লিকেশনের আবশ্যকতা ভিত্তিতে উপযুক্ত আইসোলেশন স্তর নির্বাচন করা উচিৎ।