आप जिस समस्या का सामना कर रहे हैं वह इसलिए होती है क्योंकि MySQL केवल उस मान के लिए तालिका पंक्ति को लॉक नहीं करता है जिसे आप सम्मिलित करने जा रहे हैं, यह पिछले id
के बीच सभी संभावित मानों को लॉक कर देता है। और अगली आईडी क्रम में, इसलिए, अपने उदाहरण का पुन:उपयोग करें:
DROP TABLE IF EXISTS foo;
CREATE TABLE `foo` (
`i` INT(11) NOT NULL,
`j` INT(11) DEFAULT NULL,
PRIMARY KEY (`i`),
UNIQUE KEY `jk` (`j`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
INSERT INTO foo VALUES (5,5), (8,8), (11,11);
मान लीजिए कि आप लेन-देन TX1 से शुरू करते हैं:
START TRANSACTION;
REPLACE INTO foo VALUES(8,8);
फिर अगर आप लेन-देन शुरू करते हैं TX2
, जो कुछ भी INSERT
या REPLACE
id
. का उपयोग करके 5 और 11 के बीच लॉक हो जाएगा:
START TRANSACTION;
REPLACE INTO foo VALUES(11,11);
ऐसा लगता है कि MySQL यहां वर्णित "प्रेत समस्या" से बचने के लिए इस तरह के लॉकिंग का उपयोग करता है:http://dev.mysql.com/doc/refman/5.0/en/innodb-next-key-locking.html , MySQL एक "नेक्स्ट-की लॉकिंग" का उपयोग करता है, जो इंडेक्स-रो लॉकिंग को गैप लॉकिंग के साथ जोड़ता है, इसका मतलब है कि यह हमारे लिए पिछली और अगली आईडी के बीच कई संभावित आईडी को लॉक कर देगा, और पिछली और अगली आईडी को भी लॉक कर देगा। ।
इससे बचने के लिए एक सर्वर एल्गोरिथम बनाने का प्रयास करें जो आपके रिकॉर्ड को सम्मिलित करता है ताकि विभिन्न लेनदेन में डाले गए रिकॉर्ड ओवरलैप न हों, या कम से कम एक ही समय में आपके सभी लेनदेन निष्पादित न करें ताकि TX
एक दूसरे का इंतजार नहीं करना पड़ता।