JPA 事务不回滚
JPA Transaction not rolling back
我正在尝试进行如下所示的小示例更新:
@RestController
@RequestMapping("/customer")
public class CustomerController {
@Autowired
private EntityManager eManager;
@RequestMapping(value = "/updatepincode/pincode/{pincode}", method = RequestMethod.GET)
//@Transactional
public String updateAddress(@PathVariable("pincode") String pinCode) {
try {
eManager.getTransaction().begin();
Query query = eManager.createQuery("UPDATE Addresses SET pincode = :pincode WHERE addressid = :addressid");
int updateCount = query.setParameter("pincode", pinCode).setParameter("addressid", "714D9F99-E19E-4595-9C5A-3560C42B1389").executeUpdate();
eManager.getTransaction().commit();
if (updateCount > 0) {
System.out.println("Number of records updated = " + updateCount);
}
} catch (Exception ex) {
eManager.getTransaction().rollback();
LogService.error(this.getClass().getName(), ex);
return "Failed to update";
}
return "Record Updated";
}
}
我有意进行了此更新,以查看当我尝试使用现有主键更新另一行时抛出的异常。正如预期的那样,它抛出了 javax.persistence.PersistenceException
,原因是 com.microsoft.sqlserver.jdbc.SQLServerException
。但是在这个错误之后,我无法再打开 table 了。我敢肯定,这是因为事务没有回滚。但是正如您所看到的,我的 catch 块中有 eManager.getTransaction().rollback()
。我只能在服务停止后才能打开table。
为什么不回滚?
也尝试使用 @Transactional
注释,但没有用。
注意:我使用SQLServer 2008。其他类型的查询工作正常。如果没有违反约束,更新也可以正常工作。
这是我们在 JPA 中回滚的方式还是有其他方法?
我这样做是因为在 Hibernate 中,我做了类似 (catch
block);
if(transaction.wasCommited(){
transaction.rollback();
}
我不知道你从哪里得到这段代码,但它不应该 运行 正确。考虑重写,可能用JTA做事务管理。
@Resource public UserTransaction utx;
@Resource public EntityManagerFactory factory;
public String updateAddress(@PathVariable("pincode") String pinCode) {
EntityManager em = factory.createEntityManager();
try {
Query query = em.createQuery("UPDATE Addresses SET pincode = :pincode WHERE addressid = :addressid");
int updateCount = query.setParameter("pincode", pinCode).setParameter("addressid", "714D9F99-E19E-4595-9C5A-3560C42B1389").executeUpdate();
utx.commit();
if (updateCount > 0) {
System.out.println("Number of records updated = " + updateCount);
}
catch (RuntimeException e) {
if (utx != null) utx.rollback();
LogService.error(this.getClass().getName(), ex);
return "Failed to update";
}
finally {
em.close();
}
return "Record Updated";
}
我正在尝试进行如下所示的小示例更新:
@RestController
@RequestMapping("/customer")
public class CustomerController {
@Autowired
private EntityManager eManager;
@RequestMapping(value = "/updatepincode/pincode/{pincode}", method = RequestMethod.GET)
//@Transactional
public String updateAddress(@PathVariable("pincode") String pinCode) {
try {
eManager.getTransaction().begin();
Query query = eManager.createQuery("UPDATE Addresses SET pincode = :pincode WHERE addressid = :addressid");
int updateCount = query.setParameter("pincode", pinCode).setParameter("addressid", "714D9F99-E19E-4595-9C5A-3560C42B1389").executeUpdate();
eManager.getTransaction().commit();
if (updateCount > 0) {
System.out.println("Number of records updated = " + updateCount);
}
} catch (Exception ex) {
eManager.getTransaction().rollback();
LogService.error(this.getClass().getName(), ex);
return "Failed to update";
}
return "Record Updated";
}
}
我有意进行了此更新,以查看当我尝试使用现有主键更新另一行时抛出的异常。正如预期的那样,它抛出了 javax.persistence.PersistenceException
,原因是 com.microsoft.sqlserver.jdbc.SQLServerException
。但是在这个错误之后,我无法再打开 table 了。我敢肯定,这是因为事务没有回滚。但是正如您所看到的,我的 catch 块中有 eManager.getTransaction().rollback()
。我只能在服务停止后才能打开table。
为什么不回滚?
也尝试使用 @Transactional
注释,但没有用。
注意:我使用SQLServer 2008。其他类型的查询工作正常。如果没有违反约束,更新也可以正常工作。
这是我们在 JPA 中回滚的方式还是有其他方法?
我这样做是因为在 Hibernate 中,我做了类似 (catch
block);
if(transaction.wasCommited(){
transaction.rollback();
}
我不知道你从哪里得到这段代码,但它不应该 运行 正确。考虑重写,可能用JTA做事务管理。
@Resource public UserTransaction utx;
@Resource public EntityManagerFactory factory;
public String updateAddress(@PathVariable("pincode") String pinCode) {
EntityManager em = factory.createEntityManager();
try {
Query query = em.createQuery("UPDATE Addresses SET pincode = :pincode WHERE addressid = :addressid");
int updateCount = query.setParameter("pincode", pinCode).setParameter("addressid", "714D9F99-E19E-4595-9C5A-3560C42B1389").executeUpdate();
utx.commit();
if (updateCount > 0) {
System.out.println("Number of records updated = " + updateCount);
}
catch (RuntimeException e) {
if (utx != null) utx.rollback();
LogService.error(this.getClass().getName(), ex);
return "Failed to update";
}
finally {
em.close();
}
return "Record Updated";
}