【发布时间】:2022-07-06 23:09:41
【问题描述】:
我不明白为什么我的代码会起到幕后的作用,所以如果有人能解释一下就太好了。我面临的问题...我有 2 张桌子。一旦方法开始,我在“table1”中插入一些东西,在插入之后我开始事务。假设代码流总是会到达 transaction.rollback()。我希望第二个查询被回滚,但不是第一个。但在我看来,它们都被回滚了。
TLDR;
预期结果:
- 第一个查询已提交
- 第二个查询被回滚
目前的结果:
- 第一个查询已回滚
- 第二个查询被回滚
//Relevant imports
import java.sql.PreparedStatement;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.jdbc.Work;
public boolean myMethod(String createdBy) {
final Long messageId = ((BigInteger) myEntityManager.createNativeQuery("insert into table1(created_by) values (:createdBy) returning id")
.setParameter("createdBy", createdBy)
.getSingleResult()).longValue();
Session session = myEntityManager.unwrap(Session.class);
Transaction tx = session.beginTransaction();
session.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
String sqlInsert = "insert into table2(messageId) values (?)";
try ( PreparedStatement pstmt = conn.prepareStatement(sqlInsert)) {
for (Object[] row : unsentRecords) {
pstmt.setLong(1, messageId);
pstmt.addBatch();
}
//Execute batch
int[] sqlStatmentsStatuses = pstmt.executeBatch();
//check if some statement failed
//Let's assume it always fails,just to be explicit
boolean somethingWentWrong = atLeastOneFailed(sqlStatmentsStatuses);
somethingWentWrong = true;
if(somethingWentWrong){
tx.rollback();
}
}
}
}
}
注意:我不知道如何准确地称呼这个问题。因此,如果有人可以为问题提出更好的标题,请将其放在评论中,我会更改它。
【问题讨论】:
-
你检查过
messageId的值吗?通常,您只能在事务之外检索数据。要持久化或更新数据,您需要一个活动事务