From 10c131bbf0629d5a1a30c7968926b9bee99cc949 Mon Sep 17 00:00:00 2001 From: Jungtaek Lim Date: Mon, 9 Dec 2013 10:54:53 +0900 Subject: [PATCH] BinaryJedis.multi(TransactionBlock) should not call discard when exception occurred * In BinaryJedis.multi(TransactionBlock), multi & exec already fired before exception occured, so sending discard has no effect, and made another error ** add unit test (error inside TransactionBlock) *** Transaction with error - Redis discards transaction automatically (execabort) *** Transaction with error - Redis doesn't roll back (force to execute all) --- .../java/redis/clients/jedis/BinaryJedis.java | 10 ++-- .../commands/TransactionCommandsTest.java | 49 ++++++++++++++++++- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/main/java/redis/clients/jedis/BinaryJedis.java b/src/main/java/redis/clients/jedis/BinaryJedis.java index 92a99a2..a7f3dba 100644 --- a/src/main/java/redis/clients/jedis/BinaryJedis.java +++ b/src/main/java/redis/clients/jedis/BinaryJedis.java @@ -1685,13 +1685,9 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey public List multi(final TransactionBlock jedisTransaction) { List results = null; jedisTransaction.setClient(client); - try { - client.multi(); - jedisTransaction.execute(); - results = jedisTransaction.exec(); - } catch (Exception ex) { - jedisTransaction.discard(); - } + client.multi(); + jedisTransaction.execute(); + results = jedisTransaction.exec(); return results; } diff --git a/src/test/java/redis/clients/jedis/tests/commands/TransactionCommandsTest.java b/src/test/java/redis/clients/jedis/tests/commands/TransactionCommandsTest.java index 565c1a4..8b1daa9 100644 --- a/src/test/java/redis/clients/jedis/tests/commands/TransactionCommandsTest.java +++ b/src/test/java/redis/clients/jedis/tests/commands/TransactionCommandsTest.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Set; @@ -16,6 +17,7 @@ import redis.clients.jedis.Response; import redis.clients.jedis.Transaction; import redis.clients.jedis.TransactionBlock; import redis.clients.jedis.exceptions.JedisDataException; +import redis.clients.jedis.exceptions.JedisException; public class TransactionCommandsTest extends JedisCommandTestBase { final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; @@ -104,6 +106,50 @@ public class TransactionCommandsTest extends JedisCommandTestBase { assertEquals(expected, response); } + + @Test + public void multiBlockWithErrorRedisDiscardsTransaction() throws Exception { + // Transaction with error - Redis discards transaction automatically (Syntax Error, etc.) + TransactionBlock tb = new TransactionBlock() { + + @Override + public void execute() throws JedisException { + del("hello"); + hmset("hello", new HashMap()); + } + }; + + try { + jedis.multi(tb); + } catch (JedisDataException e) { + assertTrue(e.getMessage().contains("EXECABORT")); + } catch (Exception e) { + throw e; + } + } + + @Test + public void multiBlockWithErrorRedisForceToExecuteAllCommands() throws Exception { + // Transaction with error - Redis doesn't roll back (Type Error, Deletion of non-exist key, etc.) + jedis.del("hello2"); + TransactionBlock tb2 = new TransactionBlock() { + + @Override + public void execute() throws JedisException { + del("hello2"); + set("hello2", "hello"); + sadd("hello2", "hello2"); + } + }; + + List responses = jedis.multi(tb2); + assertEquals("OK", responses.get(1)); + assertEquals(JedisDataException.class, responses.get(2).getClass()); + + Exception exc = (JedisDataException) responses.get(2); + assertTrue(exc.getMessage().contains("WRONGTYPE")); + } + @Test public void watch() throws UnknownHostException, IOException { @@ -294,4 +340,5 @@ public class TransactionCommandsTest extends JedisCommandTestBase { assertNull(results); } -} \ No newline at end of file + +}