gpt4 book ai didi

java - 使用 Transaction with JDBI/IDBI/Dropwizard -- 回滚问题

转载 作者:IT老高 更新时间:2023-10-29 00:02:38 25 4
gpt4 key购买 nike

我在使用 IDBI 处理事务时遇到了很多麻烦。我们正在使用 dropwizard 框架,并且简单的插入、更新、选择和删除都可以找到,但现在我们似乎无法让事务正常工作。这是我正在尝试的方法

public class JDb {
private JustinTest2 jTest2 = null;
private Handle dbHandle = null;

public JDb(final IDBI idbi) {
try {
dbHandle = idbi.open();
dbHandle.getConnection().setAutoCommit(false);
jTest2 = dbHandle.attach(JustinTest2.class);
} catch( SQLException e ) {

}
}

public void writeJustin(final int styleId, final int eventId) {
dbHandle.begin();
int num = jTest2.findByStyleId(styleId);

try {
jTest2.doStuff(styleId, eventId);
dbHandle.commit();
} catch(Exception e) {
dbHandle.rollback(); // Never rolls back here, always get the inserted row!
}

num = jTest2.findByStyleId(styleId);
}
}

这是我的 JustinTest2 类(class)

public abstract class JustinTest2 {

@SqlUpdate("INSERT INTO jTest2 (styleId, jNum) VALUES (:styleId, :jNum)")
public abstract void insert(@Bind("styleId") int styleId, @Bind("jNum") int jNum);

@SqlQuery("SELECT count(styleId) " +
"FROM jTest2 " +
"WHERE styleId=:styleId")
public abstract int findByStyleId(@Bind("styleId") int styleId);


public int doStuff(int styleId, int eventId) throws Exception{
int count = findByStyleId(styleId);

insert(styleId, eventId);

count = findByStyleId(styleId);

if(count==1) {
throw new Exception("Roll back");
}

return count;
}
}

我也尝试过像这样实现 writeJustin:

public void writeJustin(final int styleId, final int eventId) throws Exception {
int rows_updated = jTest2.inTransaction(new Transaction<Integer, JustinTest2>() {
@Override
public Integer inTransaction(JustinTest2 transactional, TransactionStatus status) throws Exception {

jTest2.insert(styleId, eventId);
int num = transactional.findByStyleId(styleId);

try {
if(num == 1) throw new Exception("BOOM");
} catch (Exception e) {
transactional.rollback();
throw e;
}

num = transactional.findByStyleId(styleId);
return num;
}
});
}

我似乎无法让事务回滚,在这些方式中,无论我直接通过句柄尝试还是使用 inTransaction(根据我的理解不应该提交事务),在回滚后插入的行总是存在如果在回调中抛出异常)有人知道我可能做错了什么吗?

最佳答案

这与您的问题无关,但我将其添加为答案,因为您的问题在 Google 搜索结果中排名靠前,并且没有很多示例。

使用 JDBI v2,您可以使用 @Transaction annotation简化您的代码。只需用注解装饰公共(public)方法,JDBI 就会在幕后处理开始、提交和回滚。

public abstract class JustinTest2 {

@SqlUpdate("INSERT INTO jTest2 (styleId, jNum) VALUES (:styleId, :jNum)")
protected abstract void insert(@Bind("styleId") int styleId, @Bind("jNum") int jNum);

@SqlQuery("SELECT count(styleId) " +
"FROM jTest2 " +
"WHERE styleId=:styleId")
protected abstract int findByStyleId(@Bind("styleId") int styleId);

@Transaction
public int doStuff(int styleId, int eventId) throws Exception{
int count = findByStyleId(styleId);

insert(styleId, eventId);

count = findByStyleId(styleId);

if(count==1) {
throw new Exception("Roll back");
}

return count;
}
}

请注意,我对 insertfindByStyleId 方法进行了保护;从 public 向下强制它们在事务中一起完成(在公共(public) doStuff 方法中);不是 private 因为 JDBI 自动生成的实现将无法覆盖它们(具有 private abstract 的方法因此不起作用 - 你会强制编译器接受没有主体的方法)。

您也可以指定 TransactionIsolationLevel在注释中覆盖数据库的默认值。

@Transaction(TransactionIsolationLevel.REPEATABLE_READ)

关于java - 使用 Transaction with JDBI/IDBI/Dropwizard -- 回滚问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20794997/

25 4 0