作者热门文章
- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我在使用 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;
}
}
请注意,我对 insert
和 findByStyleId
方法进行了保护;从 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/
我是一名优秀的程序员,十分优秀!