如何在多会话/事务环境中安全地将行插入包含带有(手动)增量键的主复合键的表中.
如何获取最新的递增值column_c,LAST_INSERT_ID()不返回所需的值.
我已经调查过SELECT FOR UPDATE ... INSERT,INSERT INTO SELECT但无法决定使用哪个.
在事务安全(锁定),隔离级别和性能方面实现这一目标的最佳方法是什么.
更新 - 另一个问题
假设两个事务/会话尝试同时插入相同的column_a,column_b对(示例1,1).我如何能;
按顺序执行插入查询.所述第一插入件(事务1)应导致的1,1,复合键1,和第二(交易2)1,1,2.我需要某种锁定机制
检索插入的column_c值.我可能需要利用变量?
表定义
CREATE TABLE `table` (
`column_a` int(11) unsigned NOT NULL,
`column_b` int(11) unsigned NOT NULL,
`column_c` int(11) unsigned NOT NULL,
PRIMARY KEY (column_a, column_b, column_c)
) ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)
示例数据
+----------+----------+----------+
| column_a | column_b | column_c |
+----------+----------+----------+
| 1 | 1 | 1 |
| 1 | 1 | 2 |
| 1 | 1 | 3 |
| 2 | 1 | 1 |
| 2 | 1 | 2 |
| 2 | 1 | 3 |
+----------+----------+----------+
Run Code Online (Sandbox Code Playgroud)
将插入带入选择查询
INSERT INTO `table` (`column_a`, `column_b`, `column_c`)
SELECT 2,1, IFNULL(MAX(`column_c`), 0) + 1 FROM `table`
WHERE `column_a` = 2 and `column_b` = 1;
Run Code Online (Sandbox Code Playgroud)
BEGIN;
SELECT @c := MAX(c) + 1
FROM t
WHERE a = ? AND b = ?
FOR UPDATE; -- important
if row found -- in application code (or Stored Proc)
then
INSERT INTO t (a,b,c)
VALUES
(?, ?, @c);
else
INSERT INTO t (a,b,c)
VALUES
(?, ?, 1);
COMMIT;
Run Code Online (Sandbox Code Playgroud)
希望它将FOR UPDATE停止,直到它获得锁定和所需的c值。那么剩下的交易应该会顺利进行。
我认为设置并不transaction_isolation重要,但这值得研究。
| 归档时间: |
|
| 查看次数: |
343 次 |
| 最近记录: |