中断尝试锁定的原因

时间:2013-11-29 08:16:32

标签: hibernate jboss transactions

我的代码是随机运行的。我使用Hibernate作为ORM,使用JBoss6作为app服务器。我随机得到以下异常。我无法找出原因。

Caused by: java.sql.SQLException: Interrupted attempting lock: org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@5458ca9
    at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.tryLock(BaseWrapperManagedConnection.java:402)
    at org.jboss.jca.adapters.jdbc.WrappedConnection.lock(WrappedConnection.java:146)
    at org.jboss.jca.adapters.jdbc.WrappedConnection.prepareStatement(WrappedConnection.java:394)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:534) [hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:116) [hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109) [hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244) [hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2412) [hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    ... 31 more
12:48:50,276 ERROR [stderr] (pool-6-thread-1) org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: JDBC rollback failed
12:48:50,277 ERROR [stderr] (pool-6-thread-1)   at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:679)
12:48:50,277 ERROR [stderr] (pool-6-thread-1)   at org.springframework.transaction.support.AbstractPlatformTransactionManager.doRollbackOnCommitException(AbstractPlatformTransactionManager.java:892)
12:48:50,277 ERROR [stderr] (pool-6-thread-1)   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:782)
12:48:50,277 ERROR [stderr] (pool-6-thread-1)   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
12:48:50,277 ERROR [stderr] (pool-6-thread-1)   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147)
12:48:50,278 ERROR [stderr] (pool-6-thread-1)   at com.verisk.dep.common.aspect.DaoInterceptor.invoke(DaoInterceptor.java:38)
12:48:50,278 ERROR [stderr] (pool-6-thread-1)   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
12:48:50,278 ERROR [stderr] (pool-6-thread-1)   at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
12:48:50,278 ERROR [stderr] (pool-6-thread-1)   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
12:48:50,278 ERROR [stderr] (pool-6-thread-1)   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
12:48:50,278 ERROR [stderr] (pool-6-thread-1)   at $Proxy136.userRegistration(Unknown Source)
12:48:50,278 ERROR [stderr] (pool-6-thread-1)   at 

1 个答案:

答案 0 :(得分:2)

我遇到了类似的问题。

就我而言,我的程序有一个ThreadPool,其中一些任务以固定的速率安排,方法是java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate。

在某些特定情况下,当我必须停止并删除其中一些任务时,我使用方法java.util.concurrent.Future.cancel(boolean mayInterruptIfRunning)并将mayInterruptIfRunning设置为true。

这导致软件抛出“java.sql.SQLException:Interrupted attempt lock”异常。我认为这是因为程序取消了中断线程的任务,并且它正在运行数据库操作或类似的操作。

因此,我将mayInterruptIfRunning参数更改为false,并强制程序在任务尚未完成和取消时等待。

以下是解决方案的示例:

List<ScheduledFuture> tasks = new ArrayList<ScheduledFuture>();
ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(5);

tasks.add(threadPool.scheduleAtFixedRate(yourRunnableTask, 0L, 60000L, TimeUnit.MILLISECONDS));

...

for(int i=0; i<tasks.size(); i++)
{
    ScheduledFuture task = tasks.get(i);
    task.cancel(false);

    int retrys = 0;

    while(!task.isCancelled() && retrys < 3)
    {
        try
        {
            Thread.sleep(1000);
        }
        catch(Exception e)
        {
        }

        retrys++
    }

    if(task.isCancelled())
    {
        // This is not actually neccesary (only a good practice)
        task.cancel();
        threadPool.remove(task);
    }
}