java向數據庫插入數據時的錯誤: Duplicate entry '' for key 'PRIMARY' 問題解決


錯誤提示為:你插入的記錄與數據表中原有記錄的主鍵重復了(Duplicate)。所以插入失敗

 

mysql主鍵設置成auto_increment時,進行並發性能測試出現主鍵反復Duplicate entry 'xxx' for key 'PRIMARY'
解決方法:
在my.cnf的[mysqld]片段中加入設置innodb_autoinc_lock_mode=0
同一時候注意調大jdbc的活躍鏈接數,如設置 jdbc.maxActive=300,由於設置innodb_autoinc_lock_mode=0可能導致鏈接過多。
注意,這樣的方式僅僅須要在並發性能測試時設置,由於這樣的方式在插入記錄時需進行全表鎖定,性能較差,平時生產環境中僅僅需使用默認的設置innodb_autoinc_lock_mode=1就可以,mysql的官方文檔有說明:
1、innodb_autoinc_lock_mode = 0 (“traditional” lock mode)
這樣的方式就和mysql5.1.22曾經一樣,這樣的方式的特點就是“表級鎖定”,並發性較差
2、innodb_autoinc_lock_mode = 1 (“consecutive” lock mode)
這樣的方式是新版本號中的默認方式,推薦使用,並發性相對較高,特點是“consecutive”,即保證同一條insert語句中新插入的auto_increment id都是連續的。
這樣的模式下:
“Simple inserts”:直接通過分析語句,獲得要插入的數量,然后一次性分配足夠的auto_increment id,僅僅會將整個分配的過程鎖住。
“Bulk inserts”:由於不能確定插入的數量,因此使用和曾經的模式同樣的表級鎖定。
“Mixed-mode inserts”:直接分析語句,獲得最壞情況下須要插入的數量,然后一次性分配足夠的auto_increment id,僅僅會將整個分配的過程鎖住。須要注意的是,這樣的方式下,會分配過多的id,而導致”浪費“。比方INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');會一次性的分配5個id,而無論用戶是否指定了部分id;INSERT … ON DUPLICATE KEY UPDATE一次性分配,而無論將來插入過程中是否會由於duplicate key而只運行update操作。
注意:當master mysql版本號<5.1.22,slave mysql版本號>=5.1.22時,slave須要將innodb_autoinc_lock_mode設置為0,由於默認的 innodb_autoinc_lock_mode為1,對於INSERT … ON DUPLICATE KEY UPDATE和INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');的運行結果不同,現實環境通常會使用INSERT … ON DUPLICATE KEY UPDATE。
3、innodb_autoinc_lock_mode = 2 (“interleaved” lock mode)
這樣的模式是來一個分配一個,而不會鎖表,僅僅會鎖住分配id的過程,和innodb_autoinc_lock_mode = 1的差別在於,不會預分配多個,這樣的方式並發性最高。可是在replication中當binlog_format為statement-based時 (簡稱SBR statement-based replication)存在問題,由於是來一個分配一個,這樣當並發運行時,“Bulk inserts”在分配的時會同一時候向其它的INSERT分配,會出現主從不一致(從庫運行結果和主庫運行結果不一樣),由於binlog僅僅會記錄開始的 insert id。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM