2013-04-17 4 views
6

मैं हाइबरनेट (4.1.9.Final) और MySQL (14.14 Distrib 5.5.29, InnoDB तालिका) के साथ एक पागलपन की हद तक अजीब परिणाम मिलती है:हाइबरनेट/MySQL संगामिति मुद्दा

जब मैं का उपयोग कर डेटाबेस के लिए कुछ जारी रहती है एक धागा और इसे एक और थ्रेड का उपयोग करके लाने की कोशिश करें, हाइबरनेट हमेशा इकाई नहीं ढूंढता है।

कुछ टिप्पणियों (तथ्य यह है कि मैं ठीक से लेन-देन करने से कर रहा हूँ और लोड सत्र खोलने से पहले जारी रहती है-सत्र को समाप्त करने के बावजूद।):

  • मैं यह एक एकल का उपयोग कर पुन: पेश नहीं कर सकते हैं -प्रचारित कार्यक्रम।

  • मैं डेटाबेस में "लापता" इकाई देख सकते हैं, और

  • अगर मैं पुनः आरंभ आवेदन हाइबरनेट सफलतापूर्वक इकाई लोड कर सकते हैं।

यहां समस्या का वर्णन करने वाला एक एसएससीसीई है। (आयात संक्षिप्तता के लिए बाहर छोड़ दिया):

public class StressTest { 

    static SessionFactory sessionFactory; 

    public static void main(String[] args) throws InterruptedException, 
                ExecutionException { 

     // Configure Hibernate 
     Configuration conf = new Configuration(); 
     conf.setProperty("hibernate.dialect", 
         "org.hibernate.dialect.MySQLInnoDBDialect"); 
     conf.configure(); 

     ServiceRegistry serviceRegistry = new ServiceRegistryBuilder() 
       .applySettings(conf.getProperties()) 
       .buildServiceRegistry();   

     sessionFactory = conf.buildSessionFactory(serviceRegistry); 

     // Set up producer/consumer 
     BlockingQueue<Long> queue = new LinkedBlockingQueue<Long>(); 

     new Consumer(queue).start(); 
     new Producer(queue).start(); 
    } 

} 

class DummyEntity { 
    long id; 
    public long getId() { return id; } 
    public void setId(long id) { this.id = id; } 
} 

निर्माता वर्ग (DummyEntities बनाता है और उन्हें बनी रहती है)।

class Producer extends Thread { 

    BlockingQueue<Long> sink; 

    public Producer(BlockingQueue<Long> sink) { 
     this.sink = sink; 
    } 

    @Override 
    public void run() { 
     try { 
      while (true) { 

       Session session = StressTest.sessionFactory.openSession(); 

       DummyEntity entity = new DummyEntity(); 
       entity.setId(new Random().nextLong()); 

       session.beginTransaction(); 
       session.save(entity); 
       session.getTransaction().commit(); 
       session.close(); 

       sink.put(entity.getId()); 
      } 
     } catch (InterruptedException ignore) { 
      System.exit(-1); 
     } 
    } 
} 

उपभोक्ता वर्ग (डेटाबेस से लोड DummyEntities):

class Consumer extends Thread { 

    BlockingQueue<Long> source; 

    public Consumer(BlockingQueue<Long> source) { 
     this.source = source; 
    } 

    @Override 
    public void run() { 

     try { 
      while (true) { 

       long entityId = source.take(); 

       Session session = StressTest.sessionFactory.openSession(); 
       Object entity = session.get(DummyEntity.class, entityId); 
       session.close(); 

       if (entity == null) { 
        System.err.printf("Entity with id %d NOT FOUND", entityId); 
        System.exit(-1); 
       } 
      } 
     } catch (InterruptedException ignore) { 
      System.exit(-1); 
     } 
    } 
} 

अंत में, यहाँ DummyEntity के लिए मानचित्रण-एक्सएमएल है।

Entity with id -225971146115345 NOT FOUND 

कोई भी विचार क्यों:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
     "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping 
    default-cascade="all" 
    default-lazy="false"> 

    <class name="se.stresstest.DummyEntity"> 

     <id name="id" type="long"> 
      <generator class="assigned"/> 
     </id> 

    </class> 

</hibernate-mapping> 

जिसके परिणामस्वरूप उत्पादन हमेशा की तरह कुछ के साथ समाप्त होता?

(यह पिछले एक question का एक परिष्कृत संस्करण है।)

+0

मैंने आपके पिछले प्रश्न का उत्तर दिया जो कि उसे भी फिट कर सकता है, कृपया इसे देखें। – didierc

+0

@aioobe हाइबरनेट और/या MySQL – Eugene

+0

@Eugene के अन्य संस्करणों के बारे में क्या है, मुझे नहीं लगता कि यह एक हाइबरनेट समस्या है, और मेरे पास अन्य MySQL संस्करण नहीं हैं। अगर मैं PostgreSQL में बदल जाता हूं तो सब कुछ ठीक काम करता है। – aioobe

उत्तर

0

उपयोग MySQL5InnoDBDialect बजाय।

+0

सुझाव के लिए धन्यवाद। दुर्भाग्य से मदद नहीं की थी। : - / – aioobe

1

यह व्यवहार repeatable पढ़ें के एक सौदे आइसोलेशन मोड है, जो InnoDB के लिए डिफ़ॉल्ट लेन-देन आइसोलेशन मोड होने के अनुरूप होना कर सकते हैं:

http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html#isolevel_repeatable-read

यदि आपका आवेदन तर्क को देखने के लिए सक्षम किया जा रहा पर निर्भर है अन्य लेन-देन में प्रतिबद्ध डेटा के बाद वर्तमान लेन-देन शुरू किया गया था - repeatable की कीमत पर पढ़ने (डेटा/अन्य लेन-देन में हेरफेर का एक परिणाम के रूप में बदल जाएगा कर सकते हैं) - लिए प्रतिबद्ध पढ़ें करने के लिए लेन-देन अलगाव स्थापित करना चाहिए:

http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html#isolevel_read-committed

संबंधित मुद्दे