我不太明白这个词怎么表达
是这样的,现在有一台服务器运行数据库(server
),另外一台运行php程序(client
),浏览器(Browser
)访问client
,然后client
逻辑判断后通过http
协议对server
中的数据库进行CURD
操作
有个问题就是,如果Browser
的用户操作过快,而server
和client
之间http请求太慢的话,就会导致client
上获取的数据更新不及时,导致一些错误。。
栗子:一个用户只能买一个商品,用户点击之后,client
先读取server
的数据,判断是否已经购买,没有购买的话进行写入操作,然后购买完成,但是如果用户连着点击两次购买,两次操作一次进入client
,然后由于client
和server
之间网速或者其他一些问题,写入操作没有及时完成,造成两次购买操作的判断为此用户未购买,于是会有两次写入server
数据库的操作,就会造成错误。。
这个问题属于什么?应该怎么解决?
怪我咯2017-04-17 16:50:34
인메모리 데이터베이스 또는 NOSQL 데이터베이스를 사용하여 클라이언트와 상호작용하면 인메모리 데이터베이스가 MYSQL과 같은 관계형 데이터베이스와 "동기화"됩니다.
클라이언트의 특정 작업을 확인하기 위해 데이터베이스 쿼리가 필요한 경우 동시성이 높은 상황에서는 오류가 쉽게 발생할 수 있습니다. 예를 들어 중복된 이름이 있는지 확인하기 위해 사용자 등록을 사용할 때 이론적으로는 먼저 사용자 이름이 있는지 확인하기 위해 데이터베이스를 쿼리한 다음 실제 작업에서는 이 논리를 삽입합니다. 깨졌고, 같은 이름의 사용자가 발견되었습니다.
따라서 핵심 데이터를 관계형 데이터베이스에 넣고, 속도가 필요한 경우 인메모리 데이터베이스를 사용하세요. 중복 쿼리를 줄이려면 캐싱을 적절하게 사용하세요.
ringa_lee2017-04-17 16:50:34
일반적인 해결 방법은 서버가 먼저 토큰을 제공하는 것입니다. 토큰이 있어야만 작업이 성공할 수 있으며 토큰이 모두 사용되면 만료된 것으로 표시됩니다. 이를 통해 작업이 반복되지 않도록 할 수 있을 뿐만 아니라 전류 제한과 같은 기능도 수행할 수 있습니다.
귀하의 질문에 문제가 있습니다. 데이터베이스와 비즈니스 서버 간의 통신 보안을 위해 SSL 프로토콜을 사용할 수 있습니다.
또 다른 접근 방식은 일관된 해싱을 사용하여 ID를 증가시키지 않고 비즈니스 ID를 계산하는 것입니다. 이를 통해 많은 작업이 멱등성을 갖도록 보장할 수 있습니다. 관심이 있다면 시도해 볼 수 있습니다.
ringa_lee2017-04-17 16:50:34
토큰 할당은 물론 매우 좋은 솔루션입니다. 그러나 실제 적용에서는 다음 솔루션이 더 간결하고 효율적이라고 생각합니다.
<올>프론트엔드 js에서 처리할 경우 사용자가 두 번째 클릭을 하지 못하도록 [구매] 버튼을 클릭한 후 전체 화면 마스크가 팝업됩니다. 제거됨. 또한 플래그 비트를 사용하거나 기존 디바운스/스로틀 알고리즘을 사용할 수도 있습니다.
또한 구매 과정에서 짧은 시간(예: 10초 이내) 내에 반복 구매가 이루어지면 "반복 작업을 하지 마세요"라는 오류가 바로 반환되도록 백그라운드에서 결정합니다. . 데이터베이스 측에서는 트랜잭션을 사용하고 트랜잭션의 격리 수준을 높이거나 잠금을 사용하는 것을 고려할 수 있습니다.
일반적으로 프론트엔드 js에서 처리한 후에는 많은 문제를 피할 수 있습니다. 악의적인 사용자가 없다면 말이죠.
伊谢尔伦2017-04-17 16:50:34
동시 잠금을 추가하려면 redis, memcached 등을 사용하고 요청이 완료된 후 잠금을 해제할 수 있습니다.
// 작업의 원자성입니다. 키가 유효한 시간인 30초 내에 설정되면 0이 반환됩니다. 일반적인 요청 시간 제한은 30초입니다.
$redis->set($lock_key, 1, array("NX", "EX"=>'30'));
黄舟2017-04-17 16:50:34
위에서 보면 두 개의 서버가 있다는 것을 알 수 있습니다. 하나는 PHP를 실행하고 다른 하나는 db를 실행합니다. 그런데 왜 두 서버 간의 통신을 위해 http 프로토콜을 사용해야 할까요? mysql의 기본 연결 프로토콜을 사용하는 대신(mysql을 사용한다고 가정)? 즉, 서버의 데이터베이스에 php로 직접 접속한 후 DB를 운영해야 합니다.
귀하의 예에서 언급된 연속 삽입 문제는 테이블 구조 설계를 통해 해결할 수 있습니다. 필드에 고유 인덱스 UNIQUE를 추가할 수 있습니다. 그 밖에도 몇 가지 방법이 있는데 개인적으로 유니크 인덱스 방법을 추천합니다