
# GeminiDB Redis事务处理
#### 事务介绍
事务将应用程序的多个读、写操作捆绑在一起成为一个逻辑操作单元，是一个执行的整体，整个事务要么成功，要么失败。在一个连接中，当客户端执行multi命令后，redis开始将后续收到的命令缓存在队列中，当客户端发送exec命令时，redis按照顺序依次执行队列中的所有命令。如果有一个命令执行失败则事务回滚，所有命令要么全部成功，要么全部失败。
表1相关命令 
| 命令      | 含义                                   |
|:---|:---|
| WATCH   | 用于监视一个或多个key，如果事务执行之前该key被改动，则事务被打断。 |
| UNWATCH | 用于取消watch命令对所有key的监视。                |
| MULTI   | 用于标识一个事务块的开始。                        |
| EXEC    | 用于执行事务块内的所有命令。                       |
| DISCARD | 用于取消事务块，放弃执行事务块内的所有命令。               |
   
![](https://support.huaweicloud.com/redisug-nosql/public_sys-resources/caution_3.0-zh-cn.png)
- 使用proxy集群时，为保证事务执行的原子性，需确保事务中的所有key拥有相同的hashtag。若不使用hashtag，事务会被拆分成普通命令执行，则无法保证事务的原子性。
- 由于整个事务的执行是原子性的，要么全部成功要么全部失败，因此，在编写事务时，需要注意命令的合法性。
- 由于事务中的命令是按照顺序执行的，所以，在编写事务时，需要注意命令的先后顺序。
- 使用事务时应遵循轻量化原则，避免单次事务中打包过多命令或复杂度过高的命令，执行的事务中包含命令过多会引起请求阻塞或实例状态异常。
 
#### 代码示例
Client在事务中同时修改key1和key2，key1和key2要么同时修改成功，要么同时修改失败。
```
package nosql.cloud.huawei.jedis;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class TranscationTest {
    private static final String host = "127.0.0.1";
    private static final int port = 6379;
    private static final String pwd = "password";
    private static Jedis jedis;
    static {
        jedis = new Jedis(host, port);
        String authString = jedis.auth(password);
        if (!authString.equals("OK")) {
            jedis.close();
            jedis = null;
        }
    }
    public static void main(String[] args) {
        if (jedis == null) {
            return;
        }
        String str_key1 = "{str}key1";
        String str_key2 = "{str}key2";
        jedis.set(str_key1, "0");
        jedis.set(str_key2, "0");
        jedis.watch(str_key1);
        // 启动事务处理
        Transaction tx = jedis.multi();
        tx.set(str_key1, "500");
        tx.get(str_key1);
tx.set(str_key2, "1000");
        tx.get(str_key2);
        List<Object> result = tx.exec();
        if (result.isEmpty()) {
            System.out.println("Error: 事务执行中断");
        } else {
   System.out.println("Succ: 事务执行成功");
        }
        System.out.println("str_key1: {}, str_key2: {}", jedis.get(str_key1), jedis.get(str_key2));
        jedis.close();
    }
}
```
