com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException

com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

@Test
@Transactional
public void test(){
    //插入数据
    String a1 = personServiceImpl.saveParent(6, "A", 42); //返回事务ID
    System.out.println(a1); 
    //更新数据,加了事务propagation = Propagation.REQUIRES_NEW
    String a = sysServiceImpl.update("B"); //返回事务ID
    System.out.println(a); 
}

出现原因:锁等待超时,当前事务等待其他事务释放锁资源

personServiceImpl.saveParent执行的是insert操作,执行成功后会加X锁

sysServiceImpl.update执行的是update操作,如果where条件使用索引,会对记录加独占锁(X锁),否则会走全表扫描,会对所有记录加上 next-key 锁(记录锁 + 间隙锁),相当于把整个表锁住了

先开启一个事务执行insert操作,此时会先对表加上意向独占锁,然后对记录加独占锁,该事务没有提交,又开启一个新事务执行update操作,且where条件没有使用索引,会走全表扫描,需要对所有记录加上 next-key 锁(记录锁 + 间隙锁),但是由于前一个事务没有提交,会阻塞,所以会等待前一个事务释放锁资源。

意向共享锁和意向独占锁是表级锁,不会和行级的共享锁和独占锁发生冲突,而且意向锁之间也不会发生冲突,只会和共享表锁(lock tables ... read)和独占表锁(lock tables ... write)发生冲突

insert如果没有并发,是不加锁

你可能感兴趣的:(mysql,java,数据库)