Java 为什么从多线程向同一个表插入新记录时会出现死锁问题,
原因:org.hibernate.exception.LockAcquisitionException:无法执行语句 atorg.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123) 位于org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) 位于org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) 位于org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) 位于org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:178) 位于org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3356) 位于org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3229) 位于org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3630) 位于org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:146) 位于org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) 位于org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478) 位于org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356) 位于org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) 位于org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1454) 位于org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:511) 在org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3283)上 在org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2479)上 在org.hibernate.engine.jdbc.internal.jdbcoordinatorimpl.beforeTransactionCompletion(jdbcoordinatorimpl.java:473)上 位于org.hibernate.resource.transaction.backend.jdbc.internal.jdbResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(jdbResourceLocalTransactionCoordinatorImpl.java:178) 位于org.hibernate.resource.transaction.backend.jdbc.internal.jdbResourceLocalTransactionCoordinatorImpl.access$300(jdbResourceLocalTransactionCoordinatorImpl.java:39) 位于org.hibernate.resource.transaction.backend.jdbc.internal.jdbResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(jdbResourceLocalTransactionCoordinatorImpl.java:271) 位于org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:98) 位于org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:532) 。。。省略65个公共框架 原因:com.microsoft.sqlserver.jdbc.SQLServerException:事务(进程ID 52)在与另一个进程的锁|通信缓冲区资源上死锁,并被选为死锁受害者。重新运行事务 位于com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:232) 位于com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1672) 位于com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:460) 位于com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:405) 位于com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7535) 位于com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2438) 位于com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:208) 位于com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:183) 位于com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:348) 位于com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) 位于com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) 位于org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175) 。。。省略了83个公共框架Java 为什么从多线程向同一个表插入新记录时会出现死锁问题,,java,sql-server,Java,Sql Server,原因:org.hibernate.exception.LockAcquisitionException:无法执行语句 atorg.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123) 位于org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQL
什么是死锁? 当两个进程争夺对资源的独占访问权,但由于另一个进程正在阻止它而无法获得对该资源的独占访问权时,就会发生死锁。这将导致两个进程都无法继续的僵局。摆脱死锁的唯一方法是终止其中一个进程。SQL Server会自动检测何时发生死锁,并通过终止称为受害者的进程之一来采取行动 他们如何选择受害者? SQL Server选择工作量较少的进程来回滚该进程 因此,在您的情况下,当您有多个线程从一个特定的表中获取数据时,它们会锁定该表,并且任何进程都不能同时访问该表。在您的情况下,如果有任何线程对一个表进行选择,同时试图在该表中插入记录,可能会导致死锁 您可以在此处找到更多信息: 如何预防? 您可以使用(nolock)将
添加到您的选择中,例如:
select * from table with(nolock)
如果要添加条件,应如下所示:
select * from table with(nolock) where id = x
糟糕的是,如果您在事务进行某些更改的确切时间内使用(nolock)
执行select,则即使在事务回滚之后,您也会捕获这些更改