jfinal使用modal类.update方法,多个sql同时卡住.并且该字段越更新越少,醉了

image.pngimage.png

评论区

JM-java

2018-10-29 17:09

我用压力测试工具,发送了1200条并发请求.本来应该更新一个字段为1200的,结果只有16.这个问题需要我怎么改代码呢.真的特别急.希望波总和各位大神帮我看下.

JFinal

2018-10-29 19:44

数据库引擎由 MyIsam 改成 InnoDb 即可

JM-java

2018-10-30 09:11

是改数据库设置?改代码没用吗?波总,我看了下mysql数据库引擎没有问题.就是InnoDb.具体参数如下.
Variable_name Value
default_storage_engine InnoDB
default_tmp_storage_engine InnoDB
disabled_storage_engines
internal_tmp_disk_storage_engine InnoDB

JM-java

2018-10-30 09:11

@JFinal 是改数据库设置?改代码没用吗?波总,我看了下mysql数据库引擎没有问题.就是InnoDb.具体参数如下.
Variable_name Value
default_storage_engine InnoDB
default_tmp_storage_engine InnoDB
disabled_storage_engines
internal_tmp_disk_storage_engine InnoDB

JM-java

2018-10-30 09:26

@JFinal 波总,这个问题能从代码上解决吗? 并发更新问题有没有什么代码逻辑能够处理.现在线上环境正在跑,又不敢停.数据库的那张统计表数据完全和真实数据无法吻合.

JFinal

2018-10-30 11:10

@JM-java 要解决这个问题必须先定位问题,光是凭肉眼去看是很难找到原因的,手工制造两个线程,同时访问这部分代码,让这两个线程通过调试的方式交叉向前,看数据是在哪个地方出的问题

只要先找出原因,再解决就很容易了

红星

2018-10-30 11:58

常识问题 ,
先 select 后 update , 这两个分开的步骤在高并发下肯定有问题,

红星

2018-10-30 12:01

更新统计应该用 sql
update 表名 set 字段名 = 字段名 + 1 where id = 主键等
将整条sql 传给 mysql, 进行原子更新

JM-java

2018-10-30 16:33

@红星 问题不在这儿,关键是并发量一大就锁事务.我现在用DB.update直接语句更新都没用.一大堆sql在那儿卡起.

JM-java

2018-10-30 16:37

@红星 而且事务完毕之后,表的数据还没被更新.还在慢慢找原因.

JM-java

2018-10-30 16:46

@JFinal 波总,我用DB.update直接语句更新,出现多条sql同时处于 LOCK_WAIT 状态,时间一长,事务的锁释放了,但是数据却没有更新.也不执行语句然后我把程序关闭,正在卡住的sql就能够马上更新.并发量一大,又会出现这种问题.

JFinal

2018-10-31 09:54

@JM-java 看一下事务级别是不是被调高了:
Connection.TRANSACTION_NONE
Connection.TRANSACTION_READ_UNCOMMITTED
Connection.TRANSACTION_READ_COMMITTED
Connection.TRANSACTION_REPEATABLE_READ
Connection.TRANSACTION_SERIALIZABLE

上面的五个事务级别从上到下越来越高,jfinal 默认是倒数第二个,如果你自己调成了最后一个,那么会非常慢,如果是用的 jfinal 默认的还是很慢,可以调成第三个,具体办法是:
ActiveRecordPlugin.setTransactionLevel(Connection.TRANSACTION_READ_COMMITTED)

这第三个事务级别是 JDBC 默认的,而 jfinal 调高了一级,是为了防止部分用户的业务对事务级别要求太高,从而造成错误

当然,最后你还是要弄清楚这几个事务级别,然后根据你的业务情况进行选择

JM-java

2018-11-01 15:34

@JFinal 确实是因为这个,我把事务级别调低了之后,就没问题了.谢谢了,波总

JFinal

2018-11-01 17:13

@JM-java JDBC 默认的 Connection.TRANSACTION_READ_COMMITTED 适用于多数情况,jfinal 调高一级是为了避免某些用户的业务本身对事务级别本身要求就高,然后出错以后怪罪 jfinal,但这种事本质上是与 jfinal 无关的

JM-java

2018-11-01 17:46

@JFinal 恩,谢了.波总,这个可以在开发文档里面稍微提一下.如果不是波总提出的这个解决办法,我都还不知道怎么处理.

JFinal

2018-11-01 19:45

@JM-java 已经在文档中添加了:http://www.jfinal.com/doc/5-7

感谢你的反馈,后面有同学碰到这个问题就能节省大量时间了

年轻人

2018-11-02 14:59

波总能不能解释一下,为什么在 Connection.TRANSACTION_REPEATABLE_READ 级别下,会出现上面这个问题?

JFinal

2018-11-02 15:14

@年轻人 因为 TRANSACTION_REPEATABLE_READ 级别的事务并发性能比 TRANSACTION_READ_COMMITTED 要差

事务越是严格,并发度越低,例如最后一个 TRANSACTION_SERIALIZABLE 这个级别是的串行处理请求,也就是请求过来以后,一个一个通过,不允许并发,这个性能就会低到无法忍受

zhengwunong

2020-03-17 11:32

这个问题不错,