gpt4 book ai didi

mysql - iBatis selectKey 和事务

转载 作者:行者123 更新时间:2023-11-29 03:45:58 25 4
gpt4 key购买 nike

我在我的 Java 应用程序中使用 iBatis 和 MySQL 5。

我有一个持久实体类

public class Entity {
private int id;
private Stirng property;
// setters and getters are omitted
}

插入新实体的操作如下:

<insert id="insert" parameterClass="MyEntity">
<selectKey resultClass="int" type="post" keyProperty="id" >
select LAST_INSERT_ID() as value
</selectKey>
{CALL insert_entity(#property#)}
</insert>

事务在存储过程中管理如下:

CREATE DEFINER=`user`@`%` PROCEDURE `insert`(IN p_property VARCHAR(255))
BEGIN
START TRANSACTION;
INSERT INTO entities (property) VALUES (p_property);
-- Do more stuff that requires transaction: update more tables etc.
COMMIT;
END;

我想要实现的是将新插入的实体 ID 返回到我的 Java 代码中。在没有并发数据库更新的情况下,上面的设置将完全按照我的要求进行。不清楚的部分是并发数据库更新会发生什么 - 即 iBatis 执行 selectKey 语句的确切时间和上下文是什么 - 我猜它不会在存储过程中定义的同一事务中执行,所以返回的id可能不是我想要的实体的id。

我能想到的唯一可能的解决方案是避免使用 selectKey:

<insert id="insert" parameterClass="MyEntity">
{CALL insert_entity(#property#, #id,mode=OUT#)}
</insert>

从存储过程返回最后插入的 id:

CREATE DEFINER=`user`@`%` PROCEDURE `insert`(
IN p_property VARCHAR(255),
OUT p_id INTEGER(11),
)
BEGIN
START TRANSACTION;
INSERT INTO entities (property) VALUES (p_property);
SELECT LAST_INSERT_ID() INTO p_id;
-- Do more stuff that requires transaction: update more tables etc.
COMMIT;
END;

这个问题有没有更好的解决方案?


已编辑 LAST_INSERT_ID 的 MySQL 文档指出:

The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

所以看起来带有 selectKey 的原始解决方案在所有情况下都适用。但是,对于具有多个 INSERT 语句的复杂存储过程,第二种方法更安全。

最佳答案

首先,我必须声明一个显而易见的事实:您应该认真尝试避免在存储过程中进行自己的事务管理。

假设这是您唯一的选择,我会说后一种解决方案是我的首选,因为任何开发人员都清楚 ID 是从事务中返回的。

关于mysql - iBatis selectKey 和事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5388052/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com