2
回答
事务与另一个进程被死锁在锁资源上如何解决?
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

我用的是MSSQLSERVER 2005 数据库

在多线程中掉用了如下的方法.但是日志中包错了:

com.microsoft.sqlserver.jdbc.SQLServerException: 事务(进程 ID 57)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:197)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1493)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:390)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:340)
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4575)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1400)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:179)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:154)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:308)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.message.dao.SendTableImpl.setStatus(SendTableImpl.java:629)
    at org.message.dao.service.SendService.setStatus(SendService.java:86)
    at org.message.threadservice.SendThread.dosend(SendThread.java:235)
    at org.message.threadservice.SendThread.doit(SendThread.java:118)
    at org.message.threadservice.SendThread.run(SendThread.java:86)

 

==调用的方法如下==

    public synchronized void setStatus(long itemid,long id,int status,int modemid) throws DBException{

        Connection connection = null;
        PreparedStatement ps0 = null;
        PreparedStatement ps1 = null;
        String sql0 = "update " + ITEMTABLE + " set status = ?,setid = ?,sendtime=? where id = ? and sendid = ?";
        String sql1 = "update " + TABLE + " set succesnumber = succesnumber + 1 where id = ?";
        if (status == 4){
            sql1 = "update " + TABLE + " set failednumber = failednumber + 1 where id = ?";
        }
        try {
            connection = ClientDBConnection.getConnection();
            connection.setAutoCommit(false);
            ps0 = connection.prepareStatement(sql0);
            ps0.setInt(1, status);
            ps0.setInt(2, modemid);
            ps0.setTimestamp(3, new Timestamp(new Date().getTime()));
            ps0.setLong(4, itemid);
            ps0.setLong(5, id);
            ps0.executeUpdate();
            ps1 = connection.prepareStatement(sql1);
            ps1.setLong(1, id);
            ps1.executeUpdate();
            connection.commit();
        } catch (Exception e) {
            try {
                connection.rollback();
            } catch (SQLException e1) {
                log.error("Unable to roll back setStatus.", e1);
            }
            log.error("setStatus error", e);
            throw new DBException("setStatus error");
        } finally {
            ClientDBConnection.close(connection,ps0,ps1);
        }

    }

 

不知道什么原因,而且我用synchronized关键字,应该不是线程的死锁,怎么检查这样的错误呢?

先谢谢了!

<无标签>
举报
yuzhouliu
发帖于6年前 2回/6K+阅
顶部