某高并发场景的应用使用数据库的insert select 方式做了业务的逻辑判断限制,以实现预期的数据控制(不超出业务允许的范围),实际使用中的确是不会出现绕过业务规则的业务发生,但是正常的请求因为并发锁表导致相互等待 死锁 使得业务无法正常进行。
1. 分析sql语句 使所有sql子查询语句都走唯一索引、索引等 不要全表扫描导致产生表级别的锁
执行explain sql语句 ,把ALL类型的全表扫描的执行sql都优化成走索引执行
2. 降低事务等级为 ISOLATION_READ_COMMITTED ,缩小事务 及时commit
READ_COMMITTED 不会锁表,是Oracle的默认事务等级,MySql默认使用的REPEATABLE READ ,READ UNCOMMITTED更快 更不易锁表。
3. 分解service impl中的方法中作为整体事务的容易出错的代码,单独进行异常的捕获,防止其出现IP错误等导致数据库回滚
4. 其他业务语句涉及到同一张表的 要使用索引 避免全表扫描的update 。
发表评论