I don't understand why my code acts a curtain way so it would be awesome if someone could explain. The problem I am facing... I have 2 tables. As soon the method starts I insert something in "table1", after the inserting I start the transaction. Let's assume that code flow will always reach transaction.rollback(). I expect for the second query to be rollbacked, but not the first one. But it seems to me that both of them are rollbacked.
TLDR;
Expected result:
Current outcome:
//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();
}
}
}
}
}
NOTE: I don't know how to accurately call this question. So if someone can suggest a better title for the question put it in the comment and I will change it.
Below is Transaction#beginTransaction javadoc
Begin a unit of work and return the associated Transaction object. If a new underlying transaction is required, begin the transaction. Otherwise continue the new work in the context of the existing underlying transaction.
It says create begin new transaction if not available. In you case, you are already executing one query which is starting transaction. So when you say session.beginTransaction()
, it's not creating new transaction but returning existing transaction and that's why when you do rollback on that transaction, both queries are getting rolled back.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.