سؤال

أقوم بتطوير نظام محاسبة مزدوج الدخول وأحتاج إلى إدراج سجلات نشر دون أي فجوات في المعرف المتسلسل. نظرًا لأن جميع الوصول إلى قاعدة البيانات سيحدث من خلال تطبيق ويب ، فأنا أعتني بتوليد المعرفات باستخدام متغير ثابت متزامن:

import org.hibernate.*;

public class JournalService {    
    private static Object journalLock = new Object();    
    private Session session;

    public JournalService(Session session) {
        this.session = session;
    }

    public void insertJournalEntry(JournalEntry journalEntry) {
        Set<PostEntry> entries = journalEntry.getEntries();

        double total = 0;

        for (PostEntry entry : entries) {
            total += entry.getAmount();
        }

        if(total != 0)
            throw new InvalidParameterException("Journal entry is invalid. The sum of all entries must be zero.");

        Criteria criteria = session.createCriteria(PostEntry.class);
        criteria.setMaxResults(1);
        criteria.addOrder(Order.desc("id"));
        //here I add some other criteria
        synchronized(journalLock) {            
            PostEntry lastEntry = criteria.uniqueResult();
            long currentId = lastEntry.getId();

            for (PostEntry entry : entries) {
                entry.setId(currentId++)
                session.save(entry);
            }            
            session.save(journalEntry);
        }
    }
}

بعبارة قليلة ، تتمتع هذه الخدمة بعمر مرتبط بـ HTTPrequest الحالي وتديرها حاوية زنبركية ، إلى جانب أنني أتأكد من أن المعاملة بأكملها مرتبطة في نهاية الطلب. ستعتني الكتلة المزامنة بأي توافق ، لذا لا توجد طريقة تحدث أي فجوات في تسلسل الهوية. المشكلة الكبيرة هنا هي النفقات العامة المضافة للوصول إلى قاعدة البيانات لتحديد آخر سجل تم إدراجه الذي يطابق معايير معينة. لا أريد أن يحدث ذلك ، لذلك أعتقد أن الحل هنا هو استخدام ذاكرة التخزين المؤقت التي ستحتفظ آخر سجل تم إدخاله في المرة الأولى التي يتم تحديدها ، لذلك لا يلزم الوصول إلى قاعدة البيانات لإنشاء المعرف. سؤالي: هل هناك أي طريقة سبات خارج الصندوق لحل هذا؟ أنا جديد على السبات وسمعت عن الاستعلام ذاكرة التخزين المؤقت ، لكنني لست متأكدًا من كيفية استخدامه. لا أريد أن تحتفظ ذاكرة التخزين المؤقت بكل قيمة أقوم بتخزينها باستخدام هذه الخدمة ، فأنا فقط بحاجة إلى تخزين آخر إدخال تم إدخاله والذي يطابق معايير معينة. على سبيل المثال ، إذا قمت بتثبيت خمسة إدراج ، حيث يتطابق اثنان معايير متساوية "X" والثلاثة الأخرى يطابق معايير "Y" ، فإن ذاكرة التخزين المؤقتة فقط مخزنة (كائن إدراج آخر يطابق كل معايير). يمكنني بسهولة تنفيذ هذا بنفسي ، لكنني أفضل استخدام حل يتكامل مع API Hibernate.

هل كانت مفيدة؟

المحلول

التخزين المؤقت أكثر ملاءمة للتخزين الذي يتم الوصول إليه بشكل متكرر ولكن نادرا ما تم تعديل الأشياء. ما ليس ما تحاول القيام به. يمكنك استخدام المعاملة القابلة للتسلسل التي تمنع التحديثات المفقودة و قراءات غير متناسقة وهو ما تحاول تجنبه. ولكن يجب أن تضع في اعتبارك النفقات العامة.

// Hibernate Transaction isolation level settings
// Serializable isolation level
hibernate.connection.isolation=8

هنا يذهب ماذا SessionFactory API يقول

يتم التحكم في سلوك SessionFactory بواسطة الخصائص المقدمة في وقت التكوين. يتم تعريف هذه الخصائص على البيئة.

كحل بديل ، يمكنك إعداد اثنين من sessionfactory متميزة حيث يمكن للتسلسل واحد منهما كما هو موضح أعلاه.

نظرًا لأنك تسترجع أحدث كيان postertry الذي تم إدراجه ، أعتقد أن قفل المتشائم لا ينطبق بشكل صحيح لأن قاعدة البيانات الخاصة بك تغلق فقط postenres تم استردادها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top