Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transaction is not working as expected #82

Closed
dawnbreaks opened this issue Apr 28, 2015 · 2 comments
Closed

Transaction is not working as expected #82

dawnbreaks opened this issue Apr 28, 2015 · 2 comments

Comments

@dawnbreaks
Copy link

Th following Transaction will never commit, promises deadlock! That 's absolutely not acceptable.

object ExampleTransaction extends App {
  implicit val akkaSystem = akka.actor.ActorSystem()
  val redis = RedisClient("192.168.0.8", 6379)

  var keyX = "x"
  var keyY = "y"
  var keySum = "sum"
  //init values of x and y
  var setX = redis.set(keyX, 101)
  var setY = redis.set(keyY, 103)

  for {
     setXStatus <- setX
     setYStatus <- setY
  } yield {
    assert(setXStatus)
    assert(setYStatus)

    val redisTransaction = redis.transaction()
    redisTransaction.watch(keyX)
    redisTransaction.watch(keyY)
    var keyXFuture = redisTransaction.get(keyX);
    var keyYFuture = redisTransaction.get(keyY);
    var r = for {
        x <- keyXFuture
        y <- keyYFuture
    } yield {
        var sum = ParseNumber.parseInt(x.getOrElse(ByteString("-1"))) + ParseNumber.parseInt(y.getOrElse(ByteString("-1")))
        println("set(sum, x + y)|(x+y)=" + sum)
        redisTransaction.set(keySum, sum)
        redisTransaction.exec()
    }
     Await.result(r, 10 seconds)
  }

  Thread.sleep(1000*10)
  akkaSystem.shutdown()
}

Th following Transaction should not commit since watched keys has been changed. But it commit normally. That 's absolutely not acceptable.

object ExampleTransaction extends App {
  implicit val akkaSystem = akka.actor.ActorSystem()
  val redis = RedisClient("192.168.0.8", 6379)
  val anotherRedis = RedisClient("192.168.0.8", 6379)

  var keyX = "x"
  var keyY = "y"
  var keySum = "sum"
  //init value of x and y
  var setX = redis.set(keyX, 101)
  var setY = redis.set(keyY, 103)

  for {
     setXStatus <- setX
     setYStatus <- setY
  } yield {
    assert(setXStatus)
    assert(setYStatus)

    val redisTransaction = redis.transaction()
    redisTransaction.watch(keyX)
    redisTransaction.watch(keyY)
    var keyXFuture = redis.get(keyX);
    var keyYFuture = redis.get(keyY);

    //x and y modified by anotherRedis client
    anotherRedis.set(keyX, -101)
    anotherRedis.set(keyY, -103)
    Thread.sleep(1000)

    var r = for {
        x <- keyXFuture
        y <- keyYFuture
    } yield {
        var sum = ParseNumber.parseInt(x.getOrElse(ByteString("-1"))) + ParseNumber.parseInt(y.getOrElse(ByteString("-1")))
        println("set(sum, x + y)|(x+y)=" + sum)
        redisTransaction.set(keySum, sum)
        redisTransaction.exec()
    }

     Await.result(r, 10 seconds)
  }

  Thread.sleep(1000*10)
  akkaSystem.shutdown()
}

Hope that Transaction should be fully supported. I think Transaction should be implemented just like implemention of the blocking commands on the Lists.

Thanks & Best Regards!

@dawnbreaks dawnbreaks changed the title Transaction is working as expected Transaction is not working as expected Apr 28, 2015
@etaty
Copy link
Owner

etaty commented Apr 29, 2015

I kind of cheated the implementation of transaction. It's more like a batch of commands.
The rediscala watch command is kind of useless in 99% of case (because all the transaction commands are sent in one batch).
The best way would be to add a blocking transaction, however the transaction is "deprecated" for redis server, so I did not care much.
Lua script is the way to go.

@dawnbreaks
Copy link
Author

Ok, i got it. Thanks very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants