Mybatis Update操做返回值问题

后端的数据持久化使用的是 Mybatis ,在作高并发下帐户增减余额的时候,打算使用乐观锁来解决这个问题。在获取update操做的返回值时遇到了一个问题,彷佛 Mybatis 进行 update 操做获得的 int 返回值并非影响的行数。这下就尴尬了。java

通常而言,咱们知道当咱们使用 Mybatis 在 mapper 接口中定义 insert delete 等操做,定义一个 int 类型的返回值,经过该值是否为 0 来判断数据库中受影响的行数进而判断操做是否成功。mysql

到底 update 返回值表明什么呢?咱们来验证一下便知道了,假设有以下一张表以及两条数据:web

咱们来编写一个简单的单元测试用例来验证下,首先使用 mybatis 简单的写个 mapper 进行更新操做,其中 xml 中的内容为:sql

数据库链接配置为:数据库

接来下,咱们来编写一个简单的单元测试来验证下: update 的返回值是否是受影响的记录的条数 ,对应的单元测试代码以下:后端

由单元测试代码能够得知,咱们将要把数据库中两条记录的 phone 字段的值由 12345678 修改成 66666666 ,正常状况下, resultCode 将会返回 2 。由于 update 操做影响到数据库中这 2 条记录,这和咱们指望 2 是相符合的。那么一切正常的状况下,此次单元测试将会经过,那么咱们运行看看结果:mybatis

单元测试经过了,再查看数据库中的记录:并发

这说明 mybatis 的 update 更新操做返回值的确是返回受影响的行数……真的是这样吗?app

咱们知道,当数据库中的记录被修改以后,再次执行重复的 update 操做将不会影响到新的行数,为了验证我说的话,咱们试试:高并发

那么,按照这个逻辑:咱们再次执行这个单元测试应该是, resultCode 返回的应该是 0 ,和咱们的指望的数字 2 不一致,将会致使测试不经过。再次运行单元测试:

竟然仍是 passed ,看到这里聪明的你已经看出来了, 默认状况下,mybatis 的 update 操做返回值是记录的 matched 的条数,并非影响的记录条数。

严格意义上来将,这并非 mybatis 的返回值,mybatis 仅仅只是返回的数据库链接驱动(一般是 JDBC )的返回值,也就是说,若是驱动告知更新 2 条记录受影响,那么咱们将获得 mybatis 的返回值就会是 2 和 mybatis 自己是没有关系的。

道理我都懂,若是咱们非得要 mybatis 的 update 操做明确的返回受影响的记录条数,有没有什么办法呢?

固然是有的。

经过对 JDBC URL 显式的指定 useAffectedRows 选项,咱们将能够获得受影响的记录的条数:

?
1
jdbc:mysql: //${jdbc.host}/${jdbc.db}?useAffectedRows=true

咱们对咱们的数据库链接配置稍作修改,添加 useAffectedRows 字段:

此时,mybatis 的 update 操做返回的应该是受影响的条数了,咱们再次运行单元测试试试看:

update 操做返回的是受影响的记录条数,咱们知道为 0 和咱们预期的 2 不一致,天然而然单元测试不经过咯~。

总结

相关文章
相关标签/搜索