PHP로 복권 프로그램을 작성하고 있습니다.이 프로그램에 대한 대규모 동시 요청이 있기 때문에이 예에서는 각 상금의 수가 제한되어 있습니다. 나는 어떤 상금이 주식을 초과하는 것을보고 싶지 않다. 그래서 나는 전체 로직을 Redis 트랜잭션 (나는 PHP redis 클라이언트로 predis (https://github.com/nrk/predis) 사용)에 넣었지만이 프로그램에 대한 10 배 이상의 요청 후에 데이터베이스에서 10 개 이상의 레코드를 발견했다. 나는 이해할 수 없었다. 이유를 아는 사람은 누구입니까? 귀하의 설명에 매우 감사드립니다, 감사합니다!Redis의 트랜잭션에서 캐시 된 데이터를 가져올 수없는 이유는 무엇입니까?
$this->load->model('Lottery_model');
$money = $this->_get_lottery();//which prize do you get
if($money > 0){
$key = $this->_get_sum_key($money);
$dbmodel = $this->Lottery_model;
// Executes a transaction inside the given callable block:
$responses = $redis->transaction(function ($tx) use ($key, $money, $dbmodel){
$qty = intval($tx->get($key));
if($qty < 10){
//not exceed the stock limit
$dbmodel->add($customer, $money); // insert record into db
$tx->incr($key);
}else{
log_message('debug', $money . ' dollar exceed the limit');
}
});
}else{
log_message('debug', 'you are fail');
}
레디 스의 거래에 대한 문서를 읽은 후, 나는 위의 코드의 사용이 완전히 잘못 알고
여기 내 PHP 코드입니다. 낙관적 인 잠금 및 체크 - 앤 - 세트를 사용하여 버전을 수정했습니다.
$options = array(
'cas' => true, // Initialize with support for CAS operations
'watch' => $key, // Key that needs to be WATCHed to detect changes
'retry' => 3,
);
try{
$responses = $redis->transaction($options, function ($tx) use ($key, $money, $username, $dbmodel, &$qty){
$qty = intval($tx->get($key));
if($qty < 10){
$tx->multi();
$tx->incr($key);
$dbmodel->add($username, $money);// insert into mysql db
}else{
log_message('debug', $money . ' dollar exceed the limit');
}
});
}catch(PredisException $e){
log_message('debug', 'redis transaction failed');
}
는 그러나 문제는 데이터베이스에있는 레코드의 수는 상품의 한계를 초과하고, 레디 스에 저장된 총 수는 없을 것입니다. 이런 종류의 문제를 해결하기위한 일반적인 해결책은 무엇입니까? 이 경우 INNodb 테이블을 잠글 수 있습니까?
대단히 감사합니다! 내가 언급 한 문서를 읽었습니다. 지금 Redis 거래가 어떻게 작동하는지 알고 있습니다. 그래서 나는 CAS 솔루션으로 낙관적 인 잠금으로 코드를 변경 했으므로 이제 qty의 가치는 옳았습니다. 마침내 10에 도달했지만 데이터베이스의 레코드는 여전히 10을 훨씬 넘습니다. 왜 그런지 알고 있습니까? –
죄송합니다. 질문을 이해할 수 없습니다. –
죄송합니다. 원래 질문을 소스 코드의 두 번째 버전으로 업데이트했습니다. 새로운 질문이 거기에 있습니다. 고맙습니다! –