MYSQL select update事务超时

本文探讨了在同一事务中使用原生SQL进行数据选择后再更新时出现的事务超时问题,对比了使用Hibernate方法时该问题得以解决的情况。通过具体代码示例分析了两种方式下事务锁的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在同一个事物中 select数据后,再去update这条数据报事物超时异常
实际上由于update时一直获取不到事务锁导致的

伪代码如下
Start TX
selectEntity("select * from Entity where id=10");
updateEntity("update Entity set col1=1 where id=10");
Commit TX

在执行updateEntity时会一直等待 直到事物超时

而换用hibernate的写法却没有问题 如下
Start TX
Entity e = hibernateSession.get(entityId);
e.setProp(10);
hibernateSession.save(e);
Commit TX


这是为什么呢?
### 如何在Java中为 `SELECT ... FOR UPDATE` 设置超时时间 在Java应用中执行数据库操作时,特别是涉及到锁定行为的操作如 `SELECT ... FOR UPDATE` ,有时需要设定超时时间以防止长时间等待锁释放。这可以通过多种方式实现。 一种方法是在JDBC层面上通过设置查询的超时属性来间接影响到 `SELECT ... FOR UPDATE` 的超时特性。可以利用PreparedStatement接口提供的`setQueryTimeout(int seconds)` 方法指定一个合理的秒数作为超时时长[^1]: ```java String sql = "SELECT * FROM table_name WHERE id=? FOR UPDATE"; try (Connection conn = dataSource.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { // Set the timeout to 5 seconds. pstmt.setQueryTimeout(5); pstmt.setInt(1, someIdValue); try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { // Process result set... } } catch (SQLException e) { if ("HYT00".equals(e.getSQLState())) { System.out.println("The query has timed out."); } else { throw e; } } } ``` 另一种更为细粒度的方式是直接修改SQL语句,在某些数据库管理系统(DBMS)中允许在SQL命令本身里加入提示或者选项来自定义其行为模式。例如MySQL支持使用`LOCK IN SHARE MODE` 或者 `NOWAIT` 和 `SKIP LOCKED` 来处理并发访问冲突的情况;而对于PostgreSQL来说,则可以直接在`FOR UPDATE`后面加上`NOWAIT`或`SKIP LOCKED`关键字[^2]: 对于Oracle数据库而言,也可以采用类似的语法结构,即在`SELECT...FOR UPDATE`之后附加`WAIT n|NOWAIT`子句,其中n表示最大等待秒数,而`NOWAIT`则意味着立即报错而非阻塞等待。 需要注意的是,并不是所有的DBMS都提供相同的特性和兼容性,因此具体实施细节应当参照所使用的特定版本的手册说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值