tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
1
ZUGRIFFE
832
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    d0x d0x ist offline Rookie
    Registriert seit
    Mar 2008
    Beiträge
    7
    Hi, ich will mit hibernate folgendes realisieren:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    
    if( existiert objekt mit ID 1  )
    {
            Erhöhe objekt.accessCounter
    }
    else
    {
            Erstellte objekt und setzte accessCounter auf 0
    }
    Also wenn ein Objekt mit der ID 1 bereits in der Datenbank steht, soll object.accessCounter erhöht werden, andernfalls soll das Objekt angelegt werden.

    Das ganze muss aber Threadsafe sein.

    Was kann ich am besten dafür verwenden?
    Soll ich das Objekt Vor und Nach dem If locken?

    Ich hab dazu ein kleines Beispiel mit 3 Klassen geschrieben:

    HibernateThread.java
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    
    package priv.example.hibernate;
     
     
    import java.io.IOException;
    import java.sql.SQLException;
     
    public class HibernateThread extends Thread
    {
        public static void main(String[] args) throws SQLException, IOException
        {
            // Create a DAO object
            TupleDAO dao = new TupleDAO();
     
            // Now spawn some threads which try to manipulate the same object
            new HibernateThread(dao, 1).start();
            new HibernateThread(dao, 1).start();
        }
     
        private TupleDAO    dao;
        private int         id;
     
        public HibernateThread(TupleDAO dao, int id)
        {
            this.dao = dao;
            this.id = id;
        }
     
        @Override
        public void run()
        {
            // Try to find a object
            Tuple tuple = (Tuple) dao.find(Tuple.class, this.id);
     
            if (tuple != null)
            {
                // If it was found, increase the counter
                tuple.setAccessCounter(tuple.getAccessCounter() + 1);
                dao.update(tuple);
            }
            else
            {
                // If it wasn't found, create the obj
                tuple = new Tuple();
                tuple.setId(id);
                dao.save(tuple);
            }
        }
    }
    Tuple.java
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
    package priv.example.hibernate;
     
     
    import java.io.Serializable;
     
    import javax.persistence.Entity;
    import javax.persistence.Id;
     
    @Entity
    public class Tuple implements Serializable
    {
        private static final long   serialVersionUID    = 2932649664062369505L;
     
        @Id
        // Application generated Id @GeneratedValue(strategy = GenerationType.AUTO)
        private int                 id;
     
        private int                 accessCounter       = 0;
     
        public Tuple()
        {
        }
     
        public int getId()
        {
            return id;
        }
     
        public void setId(int id)
        {
            this.id = id;
        }
     
        public int getAccessCounter()
        {
            return accessCounter;
        }
     
        public void setAccessCounter(int accessCounter)
        {
            this.accessCounter = accessCounter;
        }
     
    }
    TupleDAO.java
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    
    package priv.example.hibernate;
     
     
    import java.io.Serializable;
     
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.AnnotationConfiguration;
     
    public class TupleDAO
    {
        private static SessionFactory   sessionFactory  = null;
     
        /*
         * Tuple Dataaccess
         */
     
        protected void update(Tuple obj)
        {
            Session session = openSession();
     
            Transaction tx = session.beginTransaction();
            session.update(obj);
            tx.commit();
     
            close(session);
        }
     
        protected void save(Tuple obj)
        {
            Session session = openSession();
     
            Transaction tx = session.beginTransaction();
            session.save(obj);
            tx.commit();
     
            close(session);
        }
     
        protected Object find(Class clazz, Serializable id)
        {
            Object obj = null;
     
            Session session = openSession();
     
            Transaction tx = session.beginTransaction();
            obj = session.get(clazz, id);
            tx.commit();
     
            close(session);
     
            return obj;
        }
     
        /*
         * Hibernate things...
         */
     
        public synchronized static Session openSession() throws HibernateException
        {
            if (sessionFactory == null)
            {
                final AnnotationConfiguration cfg = new AnnotationConfiguration();
                cfg.configure();
                sessionFactory = cfg.buildSessionFactory();
            }
            return sessionFactory.openSession();
        }
     
        public synchronized static void close(Session session)
        {
            if (session != null)
            {
                try
                {
                    session.close();
                }
                catch (HibernateException ignored)
                {
                    System.err.println("Couldn't close Session - " + ignored);
                }
            }
        }
    }


    Vielen Dank für eure Hilfe.
     

  2. #2
    gorefest gorefest ist offline Mitglied Brokat
    Registriert seit
    Apr 2009
    Beiträge
    256
    Hi,

    versuch doch mal, die Transactions nicht ins DAO sondern um den Verarbeitungsprozess zu legen.

    Spätestens, wenn Du Hibernate mit pessimistic locking betreibst, solltest Du Threadsafe sein.

    Sofern Du mit JBoss arbeitest, sollte Dich der Transaktionskoordinator Deines Entitmanagers vor solch Ungemach schützen.

    Grüße
    gore
     

Ähnliche Themen

  1. MySQL Transaktionsübegreifendes Locking?
    Von Test-Tomato im Forum Relationale Datenbanksysteme
    Antworten: 0
    Letzter Beitrag: 11.01.11, 09:59
  2. Annotation für Pessimistisches Locking
    Von AliB im Forum Enterprise Java (JEE, J2EE, Spring & Co.)
    Antworten: 0
    Letzter Beitrag: 08.10.07, 13:40
  3. Record Locking Problem
    Von marcel_m im Forum Relationale Datenbanksysteme
    Antworten: 12
    Letzter Beitrag: 29.03.07, 11:30
  4. [MySQL] row-level locking
    Von ZeroEnna im Forum Relationale Datenbanksysteme
    Antworten: 3
    Letzter Beitrag: 23.09.05, 16:37
  5. Socket von mehreren Thread öffnen ?
    Von knopper im Forum Java
    Antworten: 1
    Letzter Beitrag: 04.03.05, 11:45