我正在使用Spring Data JPA和Hibernate来创建这样的事务:
@Autowired
private PingRepository repository;
@Transactional
public void processPing(Ping ping)
{
Ping storedPing = repository.findById(ping.id);
if (storedPing == null)
{
repository.save(ping);
} else
{
if (ping.lastProcessTime > storedPing.lastProcessTime)
{
storedPing.setLastProcessTime(ping.lastProcessTime);
}
}
}
public interface PingRepository extends CrudRepository<Ping, PingKey>
{
@Lock(LockModeType.PESSIMISTIC_WRITE)
Ping findById(PingKey id);
}
虽然大部分时间上面的代码都成功了,但我也看到了很多例外情况:
caused by com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:
Deadlock found when trying to get lock; try restarting transaction
com.dripstat.alerts.app.store.PingOps$$EnhancerBySpringCGLIB$$4b6adccb.processPing(<generated>)
<more stacktrace....>
这是Ping
表更新的唯一地方。
上面的processPing()
方法怎么可能会遇到死锁?
更新:
以下是SHOW ENGINE INNODB STATUS
命令的一些相关输出:
------------------------
LATEST DETECTED DEADLOCK
------------------------
2015-12-23 05:57:47 7f23d73c6700
*** (1) TRANSACTION:
TRANSACTION 32990178, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1184, 2 row lock(s)
MySQL thread id 314344, OS thread handle 0x7f23d6480700, query id 99645000 104.197.97.45 dsprod update
insert into pings (lastProcessTime, id, type) values (1450845, '52c7e28eebb26a86fb1505b5', 'INCIDENT')
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 17 page no 4 n bits 376 index `PRIMARY` of table `alerts`.`pings` trx id 32990178 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 24; hex 353363336635646430636632336133633062623934613866; asc 53c3f5dd0cf23a3c0bb94a8f;;
1: len 3; hex 415050; asc APP;;
2: len 6; hex 000001f76076; asc `v;;
3: len 7; hex 5a000001e10b80; asc Z ;;
4: len 4; hex d67a36f8; asc z6 ;;
*** (2) TRANSACTION:
TRANSACTION 32990184, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1184, 2 row lock(s)
MySQL thread id 314341, OS thread handle 0x7f23d73c6700, query id 99645014 104.197.97.45 dsprod update
insert into pings (lastProcessTime, id, type) values (1450848, '52c7e28eebb26a86fb1505b5', 'INCIDENT')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 17 page no 4 n bits 376 index `PRIMARY` of table `alerts`.`pings` trx id 32990184 lock_mode X locks gap before rec
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 24; hex 353363336635646430636632336133633062623934613866; asc 53c3f5dd0cf23a3c0bb94a8f;;
1: len 3; hex 415050; asc APP;;
2: len 6; hex 000001f76076; asc `v;;
3: len 7; hex 5a000001e10b80; asc Z ;;
4: len 4; hex d67a36f8; asc z6 ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 17 page no 4 n bits 376 index `PRIMARY` of table `alerts`.`pings` trx id 32990184 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 24; hex 353363336635646430636632336133633062623934613866; asc 53c3f5dd0cf23a3c0bb94a8f;;
1: len 3; hex 415050; asc APP;;
2: len 6; hex 000001f76076; asc `v;;
3: len 7; hex 5a000001e10b80; asc Z ;;
4: len 4; hex d67a36f8; asc z6 ;;
*** WE ROLL BACK TRANSACTION (2)