冗余行显示在数据库中:
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
.
在这种情况下,如何获得锁以防止重复?