Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 即使使用LockModeType.悲观_写入也会死锁_Java_Spring_Hibernate_Spring Data Jpa - Fatal编程技术网

Java 即使使用LockModeType.悲观_写入也会死锁

Java 即使使用LockModeType.悲观_写入也会死锁,java,spring,hibernate,spring-data-jpa,Java,Spring,Hibernate,Spring Data Jpa,当我在1秒内触发10个请求时,org.springframework.dao.CannotAcquireLockException 发生 尽管我用@Transactional(isolation=isolation.SERIALIZABLE)标记了我的主方法(在内部调用存储库方法),并且存储库中的findBy方法具有@Lock(LockModeType.悲观的_-WRITE)注释 在一个环境中,一切正常,但在另一个环境中,会发生错误。知道为什么会发生错误吗?这两种环境中的代码是相同的 Stack

当我在1秒内触发10个请求时,
org.springframework.dao.CannotAcquireLockException
发生

尽管我用
@Transactional(isolation=isolation.SERIALIZABLE)
标记了我的主方法(在内部调用存储库方法),并且存储库中的findBy方法具有
@Lock(LockModeType.悲观的_-WRITE)
注释

在一个环境中,一切正常,但在另一个环境中,会发生错误。知道为什么会发生错误吗?这两种环境中的代码是相同的

Stacktrace 1:

{“时间戳”:“2017-08-21T12:18:16.16+0000”,“状态”:500,“错误”:“内部服务器错误”,“异常”:“org.springframework.orm.jpa.JpaSystemException”,“消息”: “com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:尝试获取锁时发现死锁;尝试重新启动事务;嵌套异常为 javax.persistence.PersistenceException:com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:尝试获取锁时发现死锁;请尝试重新启动 交易记录,“路径”:“/汽车/丰田”}

Stacktrace 2:

{“时间戳”:“2017-08-21T12:11:57.57+0000”,“状态”:500,“错误”:“内部服务器错误”,“异常”:“org.springframework.dao.CannotAcquireLockException”,“消息”:“无法执行语句;SQL[n/a]; 嵌套异常为org.hibernate.exception.LockAcquisitionException:无法执行语句,“路径”:“/cars/toyota”}


当您尝试锁定一行,但该行已被另一个事务锁定时,将引发该错误。所以超时发生了

添加
@Transactional(isolation=isolation.SERIALIZABLE)
会使情况变得更糟,因为可序列化级别意味着一个事务会锁定整个表(现代oracle可以以某种方式控制这一点,但对于MySQl来说,它实际上是一个等待锁定同一表的事务队列)。所以第10个事务等待前9个事务并失败

事实上,我不明白为什么需要通过方法查找
上的锁。从逻辑上讲,该方法不应该修改表,因此根本不需要锁定


我建议更改逻辑,使单个调用更快,或者如果同时进行修改,甚至引入乐观锁(基于版本)。Hibernate通过添加您使用的
@Version

数据库?MySQL数据库来实现这一点。我忘了提了,对不起。你还有一些其他的线索。。。可能需要包括,我刚刚粘贴了两个StackTrace,两个都是出于相同的原因发生的。一个由jdbc处理程序捕获,另一个由hibernate处理程序捕获并由Spring抛出。大逻辑块要求在事务完成之前锁定该行。甚至为了防止从那一行读取。我只是想知道如何防止这种僵局@Transactional不会锁定整个表,因为其他行上的事务工作正常。只是同一行上的事务正在制造麻烦。