尝试合并时尝试锁定表超时

时间:2012-03-12 11:42:19

标签: java hibernate jdbc playframework

我正在尝试为Dropbox抓取工具编写测试。

我已经设置了一个Fixture,可以在加载时将数据加载到数据库中。

Fixtures.deleteDatabase();
Fixtures.loadModels("testusers.yaml");

代码

时出现问题
da = da.merge(); //exceptions gets thrown here
达到

。它抛出一个JdbcSQLException:

org.h2.jdbc.JdbcSQLException: Timeout trying to lock table "USER"; SQL statement:
select user0_.id as id7_0_, user0_.activationSent as activati2_7_0_, 
user0_.confirmationCode as confirma3_7_0_, user0_.email as email7_0_, 
user0_.first_name as first5_7_0_, user0_.isAdmin as isAdmin7_0_, 
user0_.lastLogin as lastLogin7_0_, user0_.last_name as last8_7_0_, 
user0_.passwordHash as password9_7_0_, 
user0_.recoverPasswordCode as recover10_7_0_, 
user0_.referralCode as referra11_7_0_, 
user0_.signupDate as signupDate7_0_ from User user0_ where user0_.id=? [50200-149]

at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
at org.h2.message.DbException.get(DbException.java:167)
at org.h2.message.DbException.get(DbException.java:144)
at org.h2.table.RegularTable.doLock(RegularTable.java:499)
at org.h2.table.RegularTable.lock(RegularTable.java:433)
at org.h2.table.TableFilter.lock(TableFilter.java:140)
at org.h2.command.dml.Select.queryWithoutCache(Select.java:571)
at org.h2.command.dml.Query.query(Query.java:257)
at org.h2.command.dml.Query.query(Query.java:227)
at org.h2.command.CommandContainer.query(CommandContainer.java:78)
at org.h2.command.Command.executeQuery(Command.java:178)
at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
at org.hibernate.loader.Loader.doQuery(Loader.java:802)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2037)
... 36 more

UpdateDropboxRowJob.java,抛出异常

package mashpan.crawl.jobs;

import play.Logger;
import play.jobs.*;
import models.DropboxAuthentication;

public class UpdateDropboxRowJob extends Job {

    private DropboxAuthentication da;
    private long count;
    private boolean crawled;

    public UpdateDropboxRowJob(DropboxAuthentication da, long count, boolean crawled) {
        Logger.debug("[UpdateDropboxRowJob] ctor: "
                +",[da=" + (da == null ? "null" : da.toString()) + "]"
                +", count=[" + count + "]"
                +", crawled=[" + crawled + "]"
                );
        this.da = da;
        this.count = count;
        this.crawled = crawled;
    }

    @Override
    public void doJob() throws Exception {
        Logger.debug("[UpdateDropboxRowJob] doJob: "
                +"da=[" + (da == null ? "null" : da.toString()) + "]"
                +"count=[" + count + "]"
                +"crawled=[" + crawled + "]"
                +"da.count"+(da == null ? "da==null" : da.count) + "]"
                );
        da = da.merge(); //exceptions gets thrown here
        da.count = this.count;
        da.crawled = this.crawled;
        da.save();
    }
}



@Entity
public class DropboxAuthentication extends Model {

    public String type;

    //public String email;

    public String token_key;

    public String token_secret;

    public long count;

    public boolean crawled;

    public byte[] cipher;

    public byte[] iv;

    public long lastCrawlTime;

    @OneToOne
    public User user;

    public DropboxAuthentication(String type, byte[] cipher, byte[] iv, String token_key, String token_secret, User u, Date issueDate) 
    {
        this.type = type;
        this.cipher = cipher;
        this.iv = iv;
        this.token_key = token_key;
        this.token_secret = token_secret;
        this.user = u;
    }

    @Override
    public String toString() {
        return "DropboxAuthentication [type=" + type + ", token_key="
                + token_key + ", token_secret=" + token_secret + ", count="
                + count + ", crawled=" + crawled + ", cipher="
                + Arrays.toString(cipher) + ", iv=" + Arrays.toString(iv)
                + ", lastCrawlTime=" + lastCrawlTime + ", user=" + user + "]";
    }
}

我认为交易存在问题,我试图做

JPA.em().getTransaction().commit();

但我给了我另一个例外,即交易未激活。令人惊讶的是

JPA.em().getTransaction().begin();
JPA.em().getTransaction().commit();

抛出一个异常,即已经有一个事务正在运行。

因此,主要问题可能是游戏如何处理测试模式下的交易

播放框架:1.2.3

** * ** * ** * 的** 更新 ** * ** * ** * ****

我从

更改了我的application.conf
%db=mem

%test.db=mysql://USER:PASSWORD@localhost/development

在下文中,我得到了一个不同的异常(与之前的行相同):

javax.persistence.EntityNotFoundException: Unable to find models.User with id 1
    at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:133)
    at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:233)
    at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285)
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)
    at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:1038)
    at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:630)
    at org.hibernate.type.EntityType.resolve(EntityType.java:438)
    at org.hibernate.type.EntityType.replace(EntityType.java:298)
    at org.hibernate.type.AbstractType.replace(AbstractType.java:176)
    at org.hibernate.type.TypeHelper.replace(TypeHelper.java:212)
    at org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:600)
    at org.hibernate.event.def.DefaultMergeEventListener.mergeTransientEntity(DefaultMergeEventListener.java:337)
    at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:303)
    at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:258)
    at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:84)
    at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:867)
    at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:851)
    at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:855)
    at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:686)
    at play.db.jpa.GenericModel.merge(GenericModel.java:211)
    at mashpan.crawl.jobs.UpdateDropboxRowJob.doJob(UpdateDropboxRowJob.java:33)
    at play.jobs.Job.doJobWithResult(Job.java:50)
    at play.jobs.Job.call(Job.java:146)

然而,查看数据库我发现用户实际上已经存在。

1 个答案:

答案 0 :(得分:0)

是否有可能同时调用该作业?或者还有一些其他服务器代码也写入DropboxAuthentication表?

如果是这样,也许您可​​以尝试通过this来增加H2数据库的锁定超时,看它是否有所作为。