同步方法可能未释放锁定

公牛的分支

今天,我遇到了一个问题,该问题推测一种方法未释放锁,从而导致了死锁情况。

环境:

这是tomcat上的网络应用程序,当用户从UI调用服务器时,线程将进入servlet。Servlet具有自动装配的spring bean,其中通过servlet中的方法调用bean中的方法。

该方法是同步的,它所做的就是通过spring jdbc模板和String列表进行批量插入(Oracle DB)。(2行代码,1个jdbcTemplate批处理更新和一个日志)

在测试我的浏览器挂起后,我关闭了它,但没有人能够输入同步方法。

在这种环境下使用同步时,在这种情况下我是否需要记住一些事情?有人对可能发生的事情有猜测吗?如何保证一段时间后将释放锁?

谢谢

public class LockManager  {    

private JdbcTemplate jdbcTemplate;

private static final Log LOG = LogFactory.getLog(LockManager.class);


/* synchronized to guarantee that only one thread at a time is inserting. */
public synchronized void lockTransactions(final List<String> idList, final String userID) throws MyException{

    try{
        final Timestamp occuranceTime = new Timestamp(System.currentTimeMillis());
        jdbcTemplate.batchUpdate(INSERT_ID, new LockInsertBatchPreparedStatementSetter(idList,userID, occuranceTime));
        LOG.info("Lock Rows completed. ID List size="+idList.size());
    }catch(Exception e){
        handleInsertException(e);
    }
}



public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
}

/* Throw appropriate exception. */
private void handleInsertException(final Exception e) throws MyException{
    String message = e.getMessage();
    MyException me = null;
    if(message.contains("ORA-00001")){
       me= new MyException(ExceptionMessage.LOCK_CONSTRAINT.getMessage(),e);
    }else{
       me= new MyException(ExceptionMessage.LOCK_ERROR.getMessage(),e);
    }
    LOG.error("Exception while locking  IDs",me);
    throw me;
}


private class LockInsertBatchPreparedStatementSetter implements BatchPreparedStatementSetter{

    private List<String> idList;
    private String userID;
    private Timestamp occuranceTime;

    private  final Log LOG = LogFactory.getLog(LockInsertBatchPreparedStatementSetter.class);


    public LockInsertBatchPreparedStatementSetter(final List<String> idList, final String userID, final Timestamp occuranceTime){
        this.idList = idList;
        this.userID = userID;
        this.occuranceTime=occuranceTime;
    }

    @Override
    public int getBatchSize() {
        return idList.size();
    }

    @Override
    public void setValues(PreparedStatement ps, int i) throws SQLException {
        String thisID= idList.get(i);
        ps.setString(1, thisID);
        ps.setString(2, userID);
        ps.setTimestamp(3, occuranceTime);
        LOG.info("Attempting to Lock  ID:"+thisID+ " for user:"+userID);

    }
}

}

阿桑

首先,您应确保同步方法仅包含需要同步的代码。

其次,如果您正在执行如上所述的类似DB写的操作(批处理插入(Oracle DB)),请确保对此类操作设置超时。如果您的批处理插入时间太长,可能由于多种原因而发生。超时应该有助于快速完成任务,或者直接退出而不完成任务。

同步方法内部的任何缓慢操作,肯定会成为其他尝试进入该方法的线程的杀手。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

进入非同步块时,同步方法是否释放锁定?

来自分类Dev

Java同步方法未锁定对象

来自分类Dev

扩展类同步方法锁定

来自分类Dev

同步方法是否对此锁定

来自分类Dev

调用RMI方法是否释放同步锁?

来自分类Dev

JPA乐观锁定与同步Java方法

来自分类Dev

实例的同步方法可以被同步语句锁定吗

来自分类Dev

同步对象可锁定一个线程并释放另一个线程

来自分类Dev

使用信号量在共享内存同步中嵌套锁定/释放调用

来自分类Dev

同步对象可锁定一个线程并释放另一个线程

来自分类Dev

锁定并释放文件

来自分类Dev

外部和内部类方法之间的锁定和同步?

来自分类Dev

Java并发性问题-锁定和同步方法

来自分类Dev

静态同步方法提供了类级别的锁定。类级别锁定是什么意思?

来自分类Dev

静态同步方法提供了类级别的锁定。类级别锁定是什么意思?

来自分类Dev

锁定和同步

来自分类Dev

如何同步/锁定变量?

来自分类Dev

flock(1)无法释放锁定

来自分类Dev

删除对象时内存未释放-在ARC中释放的正确方法不清楚

来自分类Dev

同步对象:锁定代码与锁定对象

来自分类Dev

在同步块中使用wait()方法时,JVM是否在等待notify()时释放监视器?

来自分类Dev

内存/资源未释放

来自分类Dev

堆栈内存未释放

来自分类Dev

资源未释放

来自分类Dev

“指针未释放”

来自分类Dev

_UItextContaineView内存未释放

来自分类Dev

内存/资源未释放

来自分类Dev

Android 访问来自不同线程的活动的相同实例方法,无需锁定。添加同步方法

来自分类Dev

TwoWay Collection绑定同步/锁定