1

冗長な行がデータベースに表示されています:

mysql> 
mysql> 
mysql> USE usenet;SHOW TABLES;DESCRIBE ARTICLE;DESCRIBE NEWSGROUP;SELECT * FROM NEWSGROUP;
Database changed
+------------------+
| Tables_in_usenet |
+------------------+
| ARTICLE          |
| NEWSGROUP        |
+------------------+
2 rows in set (0.00 sec)

+---------------+------------+------+-----+---------+----------------+
| Field         | Type       | Null | Key | Default | Extra          |
+---------------+------------+------+-----+---------+----------------+
| ID            | bigint(20) | NO   | PRI | NULL    | auto_increment |
| MESSAGENUMBER | int(11)    | YES  |     | NULL    |                |
| NEWSGROUP_ID  | bigint(20) | YES  | MUL | NULL    |                |
+---------------+------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| ID        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| NEWSGROUP | varchar(255) | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

+----+-------------------------------+
| ID | NEWSGROUP                     |
+----+-------------------------------+
|  1 | gwene.com.androidcentral      |
|  2 | gwene.com.androidcentral      |
|  3 | gwene.com.blogspot.emacsworld |
|  4 | gwene.com.blogspot.googlecode |
|  5 | gwene.com.blogspot.googlecode |
|  6 | gwene.com.economist           |
|  7 | gwene.com.economist           |
+----+-------------------------------+
7 rows in set (0.00 sec)

mysql> 

NEWSGROUP.newsgroup一意の値を持つ必要があります。Articleコンストラクターでデータベースをロックする必要があることはかなり確信しています。

public Article(Message message, Folder folder) {
    messageNumber = message.getMessageNumber();
    EntityManagerFactory emf;
    EntityManager em;
    emf = Persistence.createEntityManagerFactory("USENETPU");
    em = emf.createEntityManager();
    String fullNewsgroupName = folder.getFullName();
    TypedQuery<Newsgroup> query = em.createQuery("SELECT n FROM Newsgroup n WHERE n.newsgroup = :newsGroupParam", Newsgroup.class);
    query.setParameter("newsGroupParam", fullNewsgroupName);
    em.lock(query, LockModeType.PESSIMISTIC_WRITE);
    try {
        newsgroup = query.getSingleResult();
        LOG.info("found " + query.getSingleResult()); //ok
    } catch (javax.persistence.NoResultException e) {
        newsgroup = new Newsgroup(folder);
        LOG.info(e + "\ncould not find " + fullNewsgroupName); //ok
    } catch (NonUniqueResultException e) {
        LOG.info(e + "\nshould never happen\t" + fullNewsgroupName); //not ok
    }
}

ただし、そのロックは次の結果になります。

run:
DEBUG: nntp: newsrc loading /home/thufir/.newsrc
DEBUG: nntp: newsrc load: 5 groups in 35ms
[EL Info]: 2012-08-03 15:35:28.386--ServerSession(17944810)--EclipseLink, version: Eclipse Persistence Services - 2.3.0.v20110604-r9504
[EL Info]: 2012-08-03 15:35:29.526--ServerSession(17944810)--file:/home/thufir/NetBeansProjects/USENET/build/classes/_USENETPU login successful
Aug 03, 2012 3:35:30 PM net.bounceme.dur.usenet.driver.FetchBean <init>
INFO: [gwene.com.androidcentral, gwene.com.blogspot.emacsworld, gwene.com.blogspot.googlecode, gwene.com.blogspot.googlereader, gwene.com.economist]
Aug 03, 2012 3:35:31 PM net.bounceme.dur.usenet.driver.FetchBean main
SEVERE: null
javax.persistence.TransactionRequiredException: 
Exception Description: No transaction is currently active
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionWrapper.throwCheckTransactionFailedException(EntityTransactionWrapper.java:113)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionWrapper.checkForTransaction(EntityTransactionWrapper.java:50)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.checkForTransaction(EntityManagerImpl.java:1776)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.lock(EntityManagerImpl.java:1617)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.lock(EntityManagerImpl.java:1593)
    at net.bounceme.dur.usenet.model.Article.<init>(Article.java:34)
    at net.bounceme.dur.usenet.driver.FetchBean.<init>(FetchBean.java:41)
    at net.bounceme.dur.usenet.driver.FetchBean.main(FetchBean.java:21)

BUILD SUCCESSFUL (total time: 16 seconds)

それをコメントアウトすると、次の通常の実行が得られます。

run:
DEBUG: nntp: newsrc loading /home/thufir/.newsrc
DEBUG: nntp: newsrc load: 5 groups in 14ms
[EL Info]: 2012-08-03 15:36:28.103--ServerSession(17944810)--EclipseLink, version: Eclipse Persistence Services - 2.3.0.v20110604-r9504
[EL Info]: 2012-08-03 15:36:29.186--ServerSession(17944810)--file:/home/thufir/NetBeansProjects/USENET/build/classes/_USENETPU login successful
Aug 03, 2012 3:36:29 PM net.bounceme.dur.usenet.driver.FetchBean <init>
INFO: [gwene.com.androidcentral, gwene.com.blogspot.emacsworld, gwene.com.blogspot.googlecode, gwene.com.blogspot.googlereader, gwene.com.economist]
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
could not find gwene.com.androidcentral
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: found gwene.com.androidcentral
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.androidcentral
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.androidcentral
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.androidcentral
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.androidcentral
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.androidcentral
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.androidcentral
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
could not find gwene.com.blogspot.emacsworld
Aug 03, 2012 3:36:31 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
could not find gwene.com.blogspot.googlecode
Aug 03, 2012 3:36:32 PM net.bounceme.dur.usenet.model.Article <init>
INFO: found gwene.com.blogspot.googlecode
Aug 03, 2012 3:36:32 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.blogspot.googlecode
Aug 03, 2012 3:36:32 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.blogspot.googlecode
Aug 03, 2012 3:36:32 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.blogspot.googlecode
Aug 03, 2012 3:36:32 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.blogspot.googlecode
Aug 03, 2012 3:36:32 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.blogspot.googlecode
Aug 03, 2012 3:36:32 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.blogspot.googlecode
Aug 03, 2012 3:36:32 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
could not find gwene.com.economist
Aug 03, 2012 3:36:33 PM net.bounceme.dur.usenet.model.Article <init>
INFO: found gwene.com.economist
Aug 03, 2012 3:36:33 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.economist
Aug 03, 2012 3:36:33 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.economist
Aug 03, 2012 3:36:33 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.economist
Aug 03, 2012 3:36:33 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.economist
Aug 03, 2012 3:36:33 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.economist
Aug 03, 2012 3:36:33 PM net.bounceme.dur.usenet.model.Article <init>
INFO: javax.persistence.NonUniqueResultException: More than one result was returned from Query.getSingleResult()
should never happen gwene.com.economist
Aug 03, 2012 3:36:33 PM net.bounceme.dur.usenet.driver.FetchBean <init>
INFO: **************************done
BUILD SUCCESSFUL (total time: 16 seconds)

ArticleコンストラクターだけがNewsgroupエンティティをインスタンス化します。現在、テーブル生成戦略はdrop and createです。

このシナリオで重複を防ぐためにロックを取得するにはどうすればよいですか?

4

2 に答える 2

2

ロッククエリを実行する前に、トランザクションを開始する必要があります。データベース トランザクションのコンテキストでのみ何かをロックできます。

于 2012-08-07T13:59:15.477 に答える