我不知道是否忘记设置一些属性以启用此功能 我有两个事务将更改同一个表中的同一行。
val f1 = Future {
mysqlDB.withTransaction {
implicit session =>
println("one===========query begin")
val name = Tables.User.filter(_.id === 2).map(_.name).run
println("one=========="+name)
Thread.sleep(3000)
println("one update change to x-f1")
Tables.User.filter(_.id === 2).map(_.name).update(name + "-f1")
println(Tables.User.filter(_.id === 2).run)
println("one============query end")
}
}
val f2 = Future {
mysqlDB.withTransaction {
implicit session =>
println("two===========query begin")
val name = Tables.User.filter(_.id === 2).map(_.name).run
println("two==========="+name)
Thread.sleep(2800)
println("two update change to x-f2")
Tables.User.filter(_.id === 2).map(_.name).update(name + "-f2")
println(Tables.User.filter(_.id === 2).run)
println("two============query end")
}
}
Await.result(f1, 10.seconds)
Await.result(f2, 10.seconds)
我使用上面相同的代码测试postgresql和mysql(它们都处于可重复模式)。我认为" one"事务将因为并发更新而失败。
事实上,postgresql确实如此,但mysql毫无例外地运行,并且" one"交易覆盖了"二"的结果。 transaction.It意味着结果丢失非常烦人。
Run starting. Expected test count is: 2
JDBCTestSpec2:
transcation
two===========query begin
one===========query begin
one============Vector(ccc)
two==========Vector(ccc)
two update change to x-f2
Vector(UserRow(2,Vector(ccc)-f2))
two============query end
one update change to x-f1
- should lock a row(postgresql) *** FAILED ***
org.postgresql.util.PSQLException: 错误: 由于同步更新而无法串行访问
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2161)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1890)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:560)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:363)
at scala.slick.driver.JdbcInvokerComponent$UpdateInvoker$$anonfun$update$1.apply(JdbcInvokerComponent.scala:88)
at scala.slick.driver.JdbcInvokerComponent$UpdateInvoker$$anonfun$update$1.apply(JdbcInvokerComponent.scala:84)
at scala.slick.jdbc.JdbcBackend$SessionDef$class.withPreparedStatement(JdbcBackend.scala:191)
at scala.slick.jdbc.JdbcBackend$BaseSession.withPreparedStatement(JdbcBackend.scala:389)
...
transcation
two===========query begin
one===========query begin
two===========Vector(ccc)
one==========Vector(ccc)
two update change to x-f2
Vector(UserRow(2,Vector(ccc)-f2))
two============query end
one update change to x-f1
Vector(UserRow(2,Vector(ccc)-f1))
one============query end
有没有人可以帮助我?
问题解决了。我已经使用FOR UPDATE
向github发布了一些代码:
https://gist.github.com/fairjm/99ce55160d4a4adf350b
答案 0 :(得分:2)
正如所指出的,@ jilen表必须使用InnoDB存储引擎来支持MySQL中的事务。 要将表转换为InnoDB表运行语句:
ALTER TABLE table_name ENGINE = InnoDB;
注意:的
如果您需要锁定所选记录,则必须使用SELECT ... FOR UPDATE
(mysql syntax; postgresql syntax)。它是is not supported natively in Slick,但有一种解决方法:https://gist.github.com/cvogt/d9049c63fc395654c4b4
参考文献: