您的位置:首页 > 数据库 > Redis

redis的事务处理

2017-11-27 19:47 197 查看


事务处理

更新时间:2017-06-07 13:26:11

   


场景介绍

云数据库 Redis 版支持 Redis 中 定义的“事务(transaction)”机制,即用户可以使用 MULTI,EXEC,DISCARD,WATCH,UNWATCH 指令用来执行原子性的事务操作。

需要强调的是,Redis 中定义的事务,并不是关系数据库中严格意义上的事务。当 Redis 事务中的某个操作执行失败,或者用 DISCARD 取消事务时候,Redis 并不执行“事务回滚”,在使用时要注意这点。


代码示例1:两个 client 操作不同的 key

package transcation.kvstore.aliyun.com;


import java.util.List;


import redis.clients.jedis.Jedis;

import redis.clients.jedis.Transaction;


public class KVStoreTranscationTest {


static final String host = "xxxxxx.m.cnhza.kvstore.aliyuncs.com";

static final int port = 6379;

static final String password = "password";


//**注意这两个key的内容是不同的

static String client1_key = "KVStore-Transcation-1";

static String client2_key = "KVStore-Transcation-2";


public static void main(String[] args) {


Jedis jedis = new Jedis(host, port);


// ApsaraDB for Redis的实例密码

String authString = jedis.auth(password);//password


if (!authString.equals("OK")) {

System.err.println("认证失败: " + authString);

jedis.close();

return;

}


jedis.set(client1_key, "0");


//启动另一个thread,模拟另外的client

new KVStoreTranscationTest().new OtherKVStoreClient().start();


Thread.sleep(500);


Transaction tx = jedis.multi();//开始事务


//以下操作会集中提交服务器端处理,作为“原子操作”

tx.incr(client1_key);

tx.incr(client1_key);

Thread.sleep(400);//此处Thread的暂停对事务中前后连续的操作并无影响,其他Thread的操作也无法执行

tx.incr(client1_key);

Thread.sleep(300);//此处Thread的暂停对事务中前后连续的操作并无影响,其他Thread的操作也无法执行

tx.incr(client1_key);

Thread.sleep(200);//此处Thread的暂停对事务中前后连续的操作并无影响,其他Thread的操作也无法执行

tx.incr(client1_key);


List<Object> result = tx.exec();//提交执行


//解析并打印出结果

for(Object rt : result){

System.out.println("Client 1 > 事务中> "+rt.toString());

}


jedis.close();

}


class OtherKVStoreClient extends Thread{

@Override

public void run() {


    Jedis jedis = new Jedis(host, port);

    // ApsaraDB for Redis的实例密码

String authString = jedis.auth(password);// password


    if (!authString.equals("OK")) {

System.err.println("AUTH Failed: " + authString);

    jedis.close();

    return;

}


jedis.set(client2_key, "100");


for (int i = 0; i < 10; i++) {

try {

Thread.sleep(300);

} catch (InterruptedException e) {

e.printStackTrace();

}


System.out.println("Client 2 > "+jedis.incr(client2_key));

}


jedis.close();

}

}

}



运行结果1

在输入了正确的云数据库 Redis 版实例访问地址和密码之后,运行以上 Java 程序,输出结果如下。从中可以看到 client1 和 client2 在两个不同的 Thread 中,client1 所提交的事务操作都是集中顺序执行的,在此期间尽管 client2 是对另外一个 key 进行操作,它的命令操作也都被阻塞等待,直至 client1 事务中的全部操作执行完毕。
Client 2 > 101

Client 2 > 102

Client 2 > 103

Client 2 > 104

Client 1 > 事务中> 1

Client 1 > 事务中> 2

Client 1 > 事务中> 3

Client 1 > 事务中> 4

Client 1 > 事务中> 5

Client 2 > 105

Client 2 > 106

Client 2 > 107

Client 2 > 108

Client 2 > 109

Client 2 > 110



代码示例2:两个 client 操作相同的 key

对以上的代码稍作改动,使得两个 client 操作同一个 key,其余部分保持不变。
... ...


//**注意这两个key的内容现在是相同的

static String client1_key = "KVStore-Transcation-1";

static String client2_key = "KVStore-Transcation-1";


... ...



运行结果2

再次运行修改后的此 Java 程序,输出结果如下。可以看到不同 Thread 中的两个 client 在操作同一个 key,但是当 client1 利用事务机制来操作这个 key 时,client2 被阻塞不得不等待 client1 事务中的操作完全执行完毕。
Client 2 > 101

Client 2 > 102

Client 2 > 103

Client 2 > 104

Client 1 > 事务中> 105

Client 1 > 事务中> 106

Client 1 > 事务中> 107

Client 1 > 事务中> 108

Client 1 > 事务中> 109

Client 2 > 110

Client 2 > 111

Client 2 > 112

Client 2 > 113

Client 2 > 114

Client 2 > 115

转自:https://help.aliyun.com/document_detail/26370.html?spm=5176.doc26369.6.598.JgIpDf


转自:https://help.aliyun.com/document_detail/26370.html?spm=5176.doc26369.6.598.JgIpDf
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: